/**************************************************************

mv_channels.cpp (C-Munipack project)
List of channels
Copyright (C) 2012 David Motl, dmotl@volny.cz

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

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 the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

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

#include "mv_channels.h"
#include "mv_graph.h"
#include <cmunipack.h>

#define ALLOC_BY 64

// Constructor with initialization
CChannel::CChannel(TCCD_Graph *tab, int ycol, int ucol, tChannelInfo info):m_Table(tab), 
	m_Column(ycol), m_ColumnU(ucol), m_Name(NULL), m_Exported(true), m_Info(info)
{
}

// Destructor
CChannel::~CChannel(void)
{
	free(m_Name);
}

void CChannel::SetExported(bool enabled)
{
	m_Exported = enabled;
}

// Get channel name
const char *CChannel::Name(void)
{
	CmpackTabColumn info;

	if (m_Table && m_Column>=0 && !m_Name) {
		cmpack_tab_get_column(m_Table->Handle(), m_Column, CMPACK_TM_NAME, &info);
		if (info.name)
			m_Name = StrDup(info.name);
		else
			m_Name = StrDup("");
	}
	return m_Name;
}

// Get minimum value
double CChannel::Min(void) const
{
	CmpackTabColumn info;

	if (m_Table && m_Column>=0) {
		cmpack_tab_get_column(m_Table->Handle(), m_Column, CMPACK_TM_RANGE, &info);
		if (info.range_valid)
			return info.range_min;
	}
	return 0.0;
}

// Get minimum value
double CChannel::Max(void) const
{
	CmpackTabColumn info;

	if (m_Table && m_Column>=0) {
		cmpack_tab_get_column(m_Table->Handle(), m_Column, CMPACK_TM_RANGE, &info);
		if (info.range_valid)
			return info.range_max;
	}
	return 0.0;
}

// Get minimum value
double CChannel::MaxU(void) const
{
	CmpackTabColumn info;

	if (m_Table && m_ColumnU>=0) {
		cmpack_tab_get_column(m_Table->Handle(), m_ColumnU, CMPACK_TM_RANGE, &info);
		if (info.range_valid)
			return info.range_max;
	}
	return 0.0;
}

// Default Constructor
CChannels::CChannels(void):m_Count(0), m_Capacity(0), m_List(NULL)
{
}

// Destructor
CChannels::~CChannels()
{
	int i;

	for (i=0; i<m_Count; i++)
		delete m_List[i];
	free(m_List);
}

// Clear the table
void CChannels::Clear(void)
{
	int i;

	for (i=0; i<m_Count; i++)
		delete m_List[i];
	m_Count = 0;
}

// Add an aperture, if the aperture with the same id is 
// in the table, it changes its parameters
void CChannels::Add(CChannel *item)
{
	if (m_Count>=m_Capacity) {
		m_Capacity += ALLOC_BY;
		CChannel **old_list = m_List;
		m_List = (CChannel**)realloc(m_List, m_Capacity*sizeof(CChannel));
		if (!m_List) 
			free(old_list);
	}
	if (m_List)
		m_List[m_Count++] = item;
}

// Find aperture by id 
int CChannels::FindColumn(int col) const
{
	int i;

	for (i=0; i<m_Count; i++) {
		if (m_List[i]->Column() == col || m_List[i]->ColumnU() == col)
			return i;
	}
	return -1;
}

// Find aperture by id 
int CChannels::FindFirst(const char *name) const
{
	int i;

	for (i=0; i<m_Count; i++) {
		if (strcmp(m_List[i]->Name(), name)==0)
			return i;
	}
	return -1;
}

// Find aperture by id 
int CChannels::FindFirst(tChannelInfo info) const
{
	int i;

	for (i=0; i<m_Count; i++) {
		if (m_List[i]->Info() == info)
			return i;
	}
	return -1;
}

// Get aperture by index
const CChannel *CChannels::Get(int index) const
{
	if (index>=0 && index<m_Count)
		return m_List[index];
	return NULL;
}
CChannel *CChannels::Get(int index) 
{
	if (index>=0 && index<m_Count)
		return m_List[index];
	return NULL;
}

// Get column by index
int CChannels::GetColumn(int index) const
{
	if (index>=0 && index<m_Count)
		return m_List[index]->Column();
	return -1;
}

// Get column by index
int CChannels::GetColumnU(int index) const
{
	if (index>=0 && index<m_Count)
		return m_List[index]->ColumnU();
	return -1;
}

// Get name by index
const char *CChannels::GetName(int index)
{
	if (index>=0 && index<m_Count)
		return m_List[index]->Name();
	return NULL;
}

// Get channel info
tChannelInfo CChannels::GetInfo(int index) const
{
	if (index>=0 && index<m_Count)
		return m_List[index]->Info();
	return DATA_UNDEFINED;
}

// Get channel info
double CChannels::GetMin(int index) const
{
	if (index>=0 && index<m_Count)
		return m_List[index]->Min();
	return DATA_UNDEFINED;
}

// Get channel info
double CChannels::GetMax(int index) const
{
	if (index>=0 && index<m_Count)
		return m_List[index]->Max();
	return DATA_UNDEFINED;
}

// Get channel info
double CChannels::GetMaxU(int index) const
{
	if (index>=0 && index<m_Count)
		return m_List[index]->MaxU();
	return DATA_UNDEFINED;
}

// Get channel info
bool CChannels::GetExported(int index) const
{
	if (index>=0 && index<m_Count)
		return m_List[index]->Exported();
	return false;
}
