/*======================================================================================

	Program:		Range Imaging Toolkit (RITK)
	Module:			ritkOpenGLRImageControlUnit.cxx
	Version:		$Revision: 2774 $
	Date:			$Date: 2012-03-13 10:52:35 +0100 (Di, 13 Mrz 2012) $

	Copyright (c) 2010-2011
	Pattern Recognition Lab, 
    University Erlangen-Nuremberg, Germany
    All rights reserved.

	This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
	See RITKCopyright.txt for more information.

	http://www5.informatik.uni-erlangen.de/research/software/ritk

========================================================================================*/

#include "ritkOpenGLRImageControlUnit.h"

namespace ritk
{


//----------------------------------------------------------------------------
OpenGLRImageControlUnit::OpenGLRImageControlUnit( QWidget * parent, Qt::WindowFlags flags )
{
	// Std Qt
	setupUi(this);

	// Register this smart pointer
	qRegisterMetaType<std::vector<ImagePayloadVisualizationConfig> >("std::vector<ImagePayloadVisualizationConfig>");

	// Connect the elements related to the primary payload
	connect(this->m_PPComboBox,				SIGNAL(currentIndexChanged(int)),	this,	SLOT(PrimaryPayloadComboBoxIdChanged(int))			);
	connect(this->m_PPClampMinSpinBox,		SIGNAL(valueChanged(double)),		this,	SLOT(PrimaryPayloadClampLowerBoundChanged(double))	);
	connect(this->m_PPClampMaxSpinBox,		SIGNAL(valueChanged(double)),		this,	SLOT(PrimaryPayloadClampUpperBoundChanged(double))	);
	connect(this->m_PPEnableLUTCheckBox,	SIGNAL(clicked(bool)),				this,	SLOT(PrimaryPayloadEnableLUTCheckBoxChanged(bool))	);
	connect(this->m_PPLUTComboBox,			SIGNAL(currentIndexChanged(int)),	this,	SLOT(PrimaryPayloadLUTComboBoxIdChanged(int))		);
	
	// Connect the elements related to the secondary payload
	connect(this->m_SPComboBox,				SIGNAL(currentIndexChanged(int)),	this,	SLOT(SecondaryPayloadComboBoxIdChanged(int))			);
	connect(this->m_SPClampMinSpinBox,		SIGNAL(valueChanged(double)),		this,	SLOT(SecondaryPayloadClampLowerBoundChanged(double))	);
	connect(this->m_SPClampMaxSpinBox,		SIGNAL(valueChanged(double)),		this,	SLOT(SecondaryPayloadClampUpperBoundChanged(double))	);
	connect(this->m_SPEnableLUTCheckBox,	SIGNAL(clicked(bool)),				this,	SLOT(SecondaryPayloadEnableLUTCheckBoxChanged(bool))	);
	connect(this->m_SPLUTComboBox,			SIGNAL(currentIndexChanged(int)),	this,	SLOT(SecondaryPayloadLUTComboBoxIdChanged(int))			);
}


//----------------------------------------------------------------------------
OpenGLRImageControlUnit::~OpenGLRImageControlUnit()
{
}


//----------------------------------------------------------------------------
void
OpenGLRImageControlUnit::SetPayloadConfig(ImagePayloadVisualizationConfig config, bool validFlagsOnly, bool enableInterpolation)
{
	m_Config = config;
	m_Interoplate = enableInterpolation;
	m_ValidFlagsOnly = validFlagsOnly;
}


//----------------------------------------------------------------------------
void
OpenGLRImageControlUnit::ResetGUI(std::vector<ImagePayloadVisualizationConfig> Table)
{
	// Clean the index tables, and payload combo boxes
	m_PrimaryImagePayloadConfigTable.clear();
	m_PPComboBox->clear();
	m_SecondaryImagePayloadConfigTable.clear();
	m_SPComboBox->clear();

	// Update the internal tables
	m_PrimaryImagePayloadConfigTable = Table;
	m_SecondaryImagePayloadConfigTable = Table;

	// Loop over all available primary payloads
	for ( unsigned int i = 0; i < m_PrimaryImagePayloadConfigTable.size(); i++ )
	{
		// Update the primary payload combo box. This will also trigger the first signal for i=0
		m_PPComboBox->addItem(tr(m_PrimaryImagePayloadConfigTable[i].PayloadIdentifier.c_str()));
	}

	// Loop over all available Secondary payloads
	for ( unsigned int i = 0; i < m_SecondaryImagePayloadConfigTable.size(); i++ )
	{
		// Update the secondary payload combo box. This will also trigger the first signal for i=0
		m_SPComboBox->addItem(tr(m_SecondaryImagePayloadConfigTable[i].PayloadIdentifier.c_str()));
	}

	if(m_Config.ValidFlag)
	{
		m_PPComboBox->setCurrentIndex(m_Config.PayloadId);
		m_SPComboBox->setCurrentIndex(m_Config.PayloadId);
		m_ValidFlagsCheckBox->setChecked(m_ValidFlagsOnly);
		m_InterpolateTextureCheckBox->setChecked(m_Interoplate);
		if(m_Config.UseClamping)
		{
			m_PPClampMinSpinBox->setValue(m_Config.ClampBounds[0]);
			m_PPClampMaxSpinBox->setValue(m_Config.ClampBounds[1]);
		}
	}
}


//----------------------------------------------------------------------------
void
OpenGLRImageControlUnit::PrimaryPayloadComboBoxIdChanged(int id)
{
	// Sanity check
	if ( id < 0 )
		return;

	// Update the GUI 
	if ( m_PrimaryImagePayloadConfigTable[id].UseClamping )
	{
		// Enable the input widgets
		m_PPClampGroupBox->setEnabled(true);
		m_PPClampGroupBox->setVisible(true);
		m_PPClampMaxSpinBox->setEnabled(true);
		m_PPClampMinSpinBox->setEnabled(true);
		m_PPClampPushButton->setEnabled(true);

		// Update the input widget's values based on the selected item and associated payload descriptor
		m_PPClampMinSpinBox->setValue(m_PrimaryImagePayloadConfigTable[id].ClampBounds[0]);
		m_PPClampMaxSpinBox->setValue(m_PrimaryImagePayloadConfigTable[id].ClampBounds[1]);
	}
	else
	{
		// Disable the input widgets as we can't handle them
		m_PPClampGroupBox->setEnabled(false);
		m_PPClampGroupBox->setVisible(false);
		m_PPClampMaxSpinBox->setEnabled(false);
		m_PPClampMinSpinBox->setEnabled(false);
		m_PPClampPushButton->setEnabled(false);
	}

	// Update the enable LUT check box
	m_PPEnableLUTCheckBox->setChecked(m_PrimaryImagePayloadConfigTable[id].UseLUT);

	// Update the LUT combo box
	m_PPLUTComboBox->setCurrentIndex(m_PrimaryImagePayloadConfigTable[id].LUTID);

	// Resolve and emit the PrimaryPayloadChanged() signal
	emit PrimaryPayloadVisualizationConfigChanged(m_PrimaryImagePayloadConfigTable[id]);
}


//----------------------------------------------------------------------------
void
OpenGLRImageControlUnit::SecondaryPayloadComboBoxIdChanged(int id)
{
	if ( id < 0 )
		return;

	// Update the GUI based on the selected image type
	if ( m_SecondaryImagePayloadConfigTable[id].UseClamping )
	{
		// Enable the input widgets
		m_SPClampGroupBox->setEnabled(true);
		m_SPClampGroupBox->setVisible(true);
		m_SPClampMaxSpinBox->setEnabled(true);
		m_SPClampMinSpinBox->setEnabled(true);
		m_SPClampPushButton->setEnabled(true);

		// Update the input widget's values based on the selected item and associated payload descriptor
		m_SPClampMinSpinBox->setValue(m_SecondaryImagePayloadConfigTable[id].ClampBounds[0]);
		m_SPClampMaxSpinBox->setValue(m_SecondaryImagePayloadConfigTable[id].ClampBounds[1]);
	}
	else
	{
		// Disable the input widgets as we can't handle them
		m_SPClampGroupBox->setEnabled(false);
		m_SPClampGroupBox->setVisible(false);
		m_SPClampMaxSpinBox->setEnabled(false);
		m_SPClampMinSpinBox->setEnabled(false);
		m_SPClampPushButton->setEnabled(false);
	}

	// Update the enable LUT check box
	m_SPEnableLUTCheckBox->setChecked(m_SecondaryImagePayloadConfigTable[id].UseLUT);

	// Update the LUT combo box
	m_SPLUTComboBox->setCurrentIndex(m_SecondaryImagePayloadConfigTable[id].LUTID);

	// Resolve and emit the SecondaryPayloadIdChanged() signal
	emit SecondaryPayloadVisualizationConfigChanged(m_SecondaryImagePayloadConfigTable[id]);
}


//----------------------------------------------------------------------------
void
OpenGLRImageControlUnit::PrimaryPayloadClampLowerBoundChanged(double value)
{
	// Update the primary payload table element corresponding to the currently selected primary payload
	int tableId = m_PPComboBox->currentIndex();
	m_PrimaryImagePayloadConfigTable[tableId].ClampBounds[0] = value;

	// Resolve and emit the PrimaryPayloadChanged() signal
	emit PrimaryPayloadVisualizationConfigChanged(m_PrimaryImagePayloadConfigTable[tableId]);
}


//----------------------------------------------------------------------------
void
OpenGLRImageControlUnit::SecondaryPayloadClampLowerBoundChanged(double value)
{
	// Update the secondary payload table element corresponding to the currently selected secondary payload
	int tableId = m_SPComboBox->currentIndex();
	m_SecondaryImagePayloadConfigTable[tableId].ClampBounds[0] = value;

	// Resolve and emit the SecondaryPayloadIdChanged() signal
	emit SecondaryPayloadVisualizationConfigChanged(m_SecondaryImagePayloadConfigTable[tableId]);
}


//----------------------------------------------------------------------------
void
OpenGLRImageControlUnit::PrimaryPayloadClampUpperBoundChanged(double value)
{
	// Update the primary payload table element corresponding to the currently selected primary payload
	int tableId = m_PPComboBox->currentIndex();
	m_PrimaryImagePayloadConfigTable[tableId].ClampBounds[1] = value;

	// Resolve and emit the PrimaryPayloadChanged() signal
	emit PrimaryPayloadVisualizationConfigChanged(m_PrimaryImagePayloadConfigTable[tableId]);
}


//----------------------------------------------------------------------------
void
OpenGLRImageControlUnit::SecondaryPayloadClampUpperBoundChanged(double value)
{
	// Update the secondary payload table element corresponding to the currently selected secondary payload
	int tableId = m_SPComboBox->currentIndex();
	m_SecondaryImagePayloadConfigTable[tableId].ClampBounds[1] = value;

	// Resolve and emit the SecondaryPayloadIdChanged() signal
	emit SecondaryPayloadVisualizationConfigChanged(m_SecondaryImagePayloadConfigTable[tableId]);
}


//----------------------------------------------------------------------------
void
OpenGLRImageControlUnit::PrimaryPayloadEnableLUTCheckBoxChanged(bool enabled)
{
	// Update the primary payload table element corresponding to the currently selected primary payload
	int tableId = m_PPComboBox->currentIndex();
	m_PrimaryImagePayloadConfigTable[tableId].UseLUT = enabled;

	// Resolve and emit the PrimaryPayloadChanged() signal
	emit PrimaryPayloadVisualizationConfigChanged(m_PrimaryImagePayloadConfigTable[tableId]);
}

//----------------------------------------------------------------------------
void
OpenGLRImageControlUnit::SecondaryPayloadEnableLUTCheckBoxChanged(bool enabled)
{
	// Update the secondary payload table element corresponding to the currently selected secondary payload
	int tableId = m_SPComboBox->currentIndex();
	m_SecondaryImagePayloadConfigTable[tableId].UseLUT = enabled;

	// Resolve and emit the SecondaryPayloadIdChanged() signal
	emit SecondaryPayloadVisualizationConfigChanged(m_SecondaryImagePayloadConfigTable[tableId]);
}


//----------------------------------------------------------------------------
void
OpenGLRImageControlUnit::PrimaryPayloadLUTComboBoxIdChanged(int id)
{
	if ( id < 0 )
		return;

	// Update the primary payload table element corresponding to the currently selected primary payload
	int tableId = m_PPComboBox->currentIndex();
	m_PrimaryImagePayloadConfigTable[tableId].LUTID = id;

	// Resolve and emit the PrimaryPayloadChanged() signal
	emit PrimaryPayloadVisualizationConfigChanged(m_PrimaryImagePayloadConfigTable[tableId]);
}


//----------------------------------------------------------------------------
void
OpenGLRImageControlUnit::SecondaryPayloadLUTComboBoxIdChanged(int id)
{
	if ( id < 0 )
		return;

	// Update the secondary payload table element corresponding to the currently selected secondary payload
	int tableId = m_SPComboBox->currentIndex();
	m_SecondaryImagePayloadConfigTable[tableId].LUTID = id;

	// Resolve and emit the SecondaryPayloadIdChanged() signal
	emit SecondaryPayloadVisualizationConfigChanged(m_SecondaryImagePayloadConfigTable[tableId]);
}


} // end namespace ritk
