/////////////////////////////////////////////////////////////
//
// ApnCamData_A285.cpp:  Implementation file for the CApnCamData_A285 class.
//
// Copyright (c) 2003-2007 Apogee Instruments, Inc.
//
/////////////////////////////////////////////////////////////

#include "ApnCamData_A285.h"

#include <stdlib.h>
#include <malloc.h>
#include <string.h>


/////////////////////////////////////////////////////////////
// Construction/Destruction
/////////////////////////////////////////////////////////////


CApnCamData_A285::CApnCamData_A285()
{
}


CApnCamData_A285::~CApnCamData_A285()
{
}


void CApnCamData_A285::Initialize()
{
	strcpy( m_Sensor, "A285" );
	strcpy( m_CameraModel, "asc285m" );
	m_CameraId = 257;
	m_InterlineCCD = true;
	m_SupportsSerialA = false;
	m_SupportsSerialB = false;
	m_SensorTypeCCD = true;
	m_TotalColumns = 1446;
	m_ImagingColumns = 1382;
	m_ClampColumns = 36;
	m_PreRoiSkipColumns = 0;
	m_PostRoiSkipColumns = 0;
	m_OverscanColumns = 28;
	m_TotalRows = 1054;
	m_ImagingRows = 1040;
	m_UnderscanRows = 12;
	m_OverscanRows = 2;
	m_VFlushBinning = 4;
	m_EnableSingleRowOffset = false;
	m_RowOffsetBinning = 1;
	m_HFlushDisable = false;
	m_ShutterCloseDelay = 0;
	m_PixelSizeX = 6.45;
	m_PixelSizeY = 6.45;
	m_Color = false;
	m_ReportedGainSixteenBit = 0.5;
	m_MinSuggestedExpTime = 0.001;
	m_CoolingSupported = true;
	m_RegulatedCoolingSupported = true;
	m_TempSetPoint = -20;
	m_TempRampRateOne = 600;
	m_TempRampRateTwo = 1800;
	m_TempBackoffPoint = 2;
	m_PrimaryADType = ApnAdType_Ascent_Sixteen;
	m_AlternativeADType = ApnAdType_Ascent_Sixteen;
	m_PrimaryADLatency = 4;
	m_AlternativeADLatency = 4;
	m_IRPreflashTime = 160;
	m_DefaultGainLeft = 52;
	m_DefaultOffsetLeft = 0;
	m_DefaultGainRight = 52;
	m_DefaultOffsetRight = 0;
	m_DefaultRVoltage = 1000;
	m_DefaultSpeed = 0x2;
	m_DefaultDataReduction = true;

	set_vpattern();

	set_hpattern_clamp_sixteen();
	set_hpattern_skip_sixteen();
	set_hpattern_roi_sixteen();

	set_hpattern_clamp_twelve();
	set_hpattern_skip_twelve();
	set_hpattern_roi_twelve();
}


void CApnCamData_A285::set_vpattern()
{
	const unsigned short Mask = 0x1E;
	const unsigned short NumElements = 48;
	unsigned short Pattern[NumElements] = 
	{
		0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x001C, 0x001C, 0x001C, 0x001C, 0x0018, 
		0x0018, 0x0018, 0x0018, 0x0018, 0x001A, 0x001A, 0x021A, 0x021A, 0x021A, 0x020A, 
		0x020A, 0x020A, 0x020A, 0x020A, 0x020A, 0x020E, 0x020E, 0x020E, 0x020E, 0x0206, 
		0x0206, 0x0206, 0x0006, 0x0006, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 
		0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0015, 0x0014
	};

	m_VerticalPattern.Mask = Mask;
	m_VerticalPattern.NumElements = NumElements;
	m_VerticalPattern.PatternData = 
		(unsigned short *)malloc(NumElements * sizeof(unsigned short));

	for ( int i=0; i<NumElements; i++ )
	{
		m_VerticalPattern.PatternData[i] = Pattern[i];
	}
}


void CApnCamData_A285::set_hpattern_skip_sixteen()
{
	const unsigned short Mask = 0x0;
	const unsigned short BinningLimit = 1;
	const unsigned short RefNumElements = 0;
	const unsigned short SigNumElements = 0;

	unsigned short *RefPatternData = NULL;

	unsigned short *SigPatternData = NULL;

	unsigned short BinNumElements[APN_MAX_HBINNING] = 
	{
		0x0011
	};

	unsigned short BinPatternData[1][256] = {
	{
		0x0008, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0008, 
		0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0009, 0x0008
	} };

	set_hpattern(	&m_SkipPatternSixteen,
					Mask,
					BinningLimit,
					RefNumElements,
					SigNumElements,
					BinNumElements,
					RefPatternData,
					SigPatternData,
					BinPatternData );
}


void CApnCamData_A285::set_hpattern_clamp_sixteen()
{
	const unsigned short Mask = 0x0;
	const unsigned short BinningLimit = 1;
	const unsigned short RefNumElements = 0;
	const unsigned short SigNumElements = 0;

	unsigned short *RefPatternData = NULL;

	unsigned short *SigPatternData = NULL;

	unsigned short BinNumElements[APN_MAX_HBINNING] = 
	{
		0x0011
	};

	unsigned short BinPatternData[1][256] = {
	{
		0x0008, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0008, 
		0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0009, 0x0008
	} };

	set_hpattern(	&m_ClampPatternSixteen,
					Mask,
					BinningLimit,
					RefNumElements,
					SigNumElements,
					BinNumElements,
					RefPatternData,
					SigPatternData,
					BinPatternData );
}


void CApnCamData_A285::set_hpattern_roi_sixteen()
{
	const unsigned short Mask = 0x0;
	const unsigned short BinningLimit = 3;
	const unsigned short RefNumElements = 0;
	const unsigned short SigNumElements = 0;

	unsigned short *RefPatternData = NULL;

	unsigned short *SigPatternData = NULL;

	unsigned short BinNumElements[APN_MAX_HBINNING] = 
	{
		0x0030, 0x0036, 0x003C
	};

	unsigned short BinPatternData[3][256] = {
	{
		0x0018, 0x801E, 0x0016, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 
		0x0014, 0x0014, 0x0014, 0x0014, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
		0x0004, 0x0084, 0x0084, 0x0004, 0x0024, 0x0024, 0x8008, 0x0008, 0x0008, 0x0008, 
		0x0008, 0x0008, 0x0008, 0x0008, 0x0108, 0x0108, 0x0008, 0x0008, 0x0008, 0x0048, 
		0x0048, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0009, 0x0008
	},
	{
		0x0018, 0x801E, 0x0016, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 
		0x0014, 0x0014, 0x0014, 0x0014, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
		0x0004, 0x0084, 0x0084, 0x0004, 0x0024, 0x0024, 0x0008, 0x0008, 0x0008, 0x0004, 
		0x0004, 0x0004, 0x8008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 
		0x0108, 0x0108, 0x0008, 0x0008, 0x0008, 0x0048, 0x0048, 0x0008, 0x0008, 0x0008, 
		0x0008, 0x0008, 0x0009, 0x0008
	},
	{
		0x0018, 0x801E, 0x0016, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 
		0x0014, 0x0014, 0x0014, 0x0014, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 
		0x0004, 0x0084, 0x0084, 0x0004, 0x0024, 0x0024, 0x0008, 0x0008, 0x0008, 0x0004, 
		0x0004, 0x0004, 0x0008, 0x0008, 0x0008, 0x0004, 0x0004, 0x0004, 0x8008, 0x0008, 
		0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0108, 0x0108, 0x0008, 0x0008, 
		0x0008, 0x0048, 0x0048, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0009, 0x0008, 
	} };

	set_hpattern(	&m_RoiPatternSixteen,
					Mask,
					BinningLimit,
					RefNumElements,
					SigNumElements,
					BinNumElements,
					RefPatternData,
					SigPatternData,
					BinPatternData );
}


void CApnCamData_A285::set_hpattern_skip_twelve()
{
	const unsigned short Mask = 0x0;
	const unsigned short BinningLimit = 1;
	const unsigned short RefNumElements = 0;
	const unsigned short SigNumElements = 0;

	unsigned short *RefPatternData = NULL;

	unsigned short *SigPatternData = NULL;

	unsigned short BinNumElements[APN_MAX_HBINNING] = 
	{
		0x0011
	};

	unsigned short BinPatternData[1][256] = {
	{
		0x0008, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0008, 
		0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0009, 0x0008
	} };

	set_hpattern(	&m_SkipPatternTwelve,
					Mask,
					BinningLimit,
					RefNumElements,
					SigNumElements,
					BinNumElements,
					RefPatternData,
					SigPatternData,
					BinPatternData );
}


void CApnCamData_A285::set_hpattern_clamp_twelve()
{
	const unsigned short Mask = 0x0;
	const unsigned short BinningLimit = 1;
	const unsigned short RefNumElements = 0;
	const unsigned short SigNumElements = 0;

	unsigned short *RefPatternData = NULL;

	unsigned short *SigPatternData = NULL;

	unsigned short BinNumElements[APN_MAX_HBINNING] = 
	{
		0x0011
	};

	unsigned short BinPatternData[1][256] = {
	{
		0x0008, 0x0006, 0x0006, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0008, 
		0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0009, 0x0008
	} };

	set_hpattern(	&m_ClampPatternTwelve,
					Mask,
					BinningLimit,
					RefNumElements,
					SigNumElements,
					BinNumElements,
					RefPatternData,
					SigPatternData,
					BinPatternData );
}


void CApnCamData_A285::set_hpattern_roi_twelve()
{
	const unsigned short Mask = 0xC;
	const unsigned short BinningLimit = 1;
	const unsigned short RefNumElements = 0;
	const unsigned short SigNumElements = 0;

	unsigned short *RefPatternData = NULL;

	unsigned short *SigPatternData = NULL;

	unsigned short BinNumElements[APN_MAX_HBINNING] = 
	{
		0x0010
	};

	unsigned short BinPatternData[1][256] = {
	{
		0x0098, 0x0096, 0x1096, 0x0894, 0x1894, 0x0114, 0x0124, 0x0024, 0x0004, 0x2008, 
		0x0808, 0x2808, 0x4208, 0x0208, 0x8049, 0x8048
	} };

	set_hpattern(	&m_RoiPatternTwelve,
					Mask,
					BinningLimit,
					RefNumElements,
					SigNumElements,
					BinNumElements,
					RefPatternData,
					SigPatternData,
					BinPatternData );
}


void CApnCamData_A285::set_hpattern(	APN_HPATTERN_FILE	*Pattern,
											unsigned short	Mask,
											unsigned short	BinningLimit,
											unsigned short	RefNumElements,
											unsigned short	SigNumElements,
											unsigned short	BinNumElements[],
											unsigned short	RefPatternData[],
											unsigned short	SigPatternData[],
											unsigned short	BinPatternData[][APN_MAX_PATTERN_ENTRIES] )
{
	int i, j;

	Pattern->Mask = Mask;
	Pattern->BinningLimit = BinningLimit;
	Pattern->RefNumElements = RefNumElements;
	Pattern->SigNumElements = SigNumElements;

	if ( RefNumElements > 0 )
	{
		Pattern->RefPatternData = 
			(unsigned short *)malloc(RefNumElements * sizeof(unsigned short));

		for ( i=0; i<RefNumElements; i++ )
		{
			Pattern->RefPatternData[i] = RefPatternData[i];
		}
	}

	if ( SigNumElements > 0 )
	{
		Pattern->SigPatternData = 
			(unsigned short *)malloc(SigNumElements * sizeof(unsigned short));

		for ( i=0; i<SigNumElements; i++ )
		{
			Pattern->SigPatternData[i] = SigPatternData[i];
		}
	}

	if ( BinningLimit > 0 )
	{
		for ( i=0; i<BinningLimit; i++ )
		{
			Pattern->BinNumElements[i] = BinNumElements[i];

			Pattern->BinPatternData[i] = 
				(unsigned short *)malloc(BinNumElements[i] * sizeof(unsigned short));

			for ( j=0; j<BinNumElements[i]; j++ )
			{
				Pattern->BinPatternData[i][j] = BinPatternData[i][j];
			}
		}
	}
}
