text:
// Written by Michael Feeney, Fanshawe College, 2010
// mfeeney@fanshawec.on.ca
// It may be distributed under the terms of the MIT License:
// http://opensource.org/licenses/MIT
// (Also, it would be Supah Cool if I heard this was remotely useful!)
// Use this code at your own risk. It is indented only as a learning aid.

//
#include "CTextureFromBMP.h"
#include <iostream>

#include <fstream>
#include <iostream>

//#define DEBUG_MODE_BITMAPREAD
//#define DEBUG_MODE_BITMAPDISPLAY
//#define DEBUG_MODE_TEXTUREREPLACEMENT

CTextureFromBMP::CTextureFromBMP()
: m_Height(0), m_Width(0), m_OriginalHeight(0), m_OriginalWidth(0), m_p_theImages(0),
  m_lastErrorNum(0), m_FileSize(0), m_offsetInBits(0), m_headerSize(0),
  m_numberOfRows(0), m_numberOfColumns(0), m_numberOfPlanes(0),
  m_bitPerPixel(0), m_compressionMode(0), m_imageSizeInBytes(0),
  m_PixelsPerMeterX(0), m_PixelsPerMeterY(0),
  m_numberOfLookUpTableEntries(0), m_numberOfImportantColours(0),
  m_textureNumber(0), m_bHave_cout_output(false), /*m_textureUnit(0),*/
  m_bIsCubeMap(false), m_bIs2DTexture(false)
{
	return;
}

CTextureFromBMP::~CTextureFromBMP()
{
	return;
}

void CTextureFromBMP::SetDebug_cout_output( bool bHave_cout_output )
{
	this->m_bHave_cout_output = bHave_cout_output;
}

GLuint CTextureFromBMP::getTextureNumber(void)
{
	return this->m_textureNumber;
}

std::string CTextureFromBMP::getTextureName(void)
{
	return this->m_textureName;
}

std::string CTextureFromBMP::getFileNameFullPath(void)
{
	return this->m_fileNameFullPath;
}

bool CTextureFromBMP::CreateNewTextureFromBMPFile2( std::string textureName, std::string fileNameFullPath,
												    /*GLenum textureUnit,*/ bool bGenerateMIPMap )
{
	bool bReturnVal = true;

	// Pick a texture number...
//	GLuint textureNum = 0;
	this->m_textureNumber = 0;
	glGenTextures( 1, &(this->m_textureNumber) );
	// Worked?
	if ( ( glGetError() & GL_INVALID_VALUE ) == GL_INVALID_VALUE )
	{
		bReturnVal = false;
		return false;
	}

	if ( !this->LoadBMP2( fileNameFullPath ) )
	{
		return false;
	}

	this->m_fileNameFullPath = fileNameFullPath;
	this->m_textureName = textureName;

	// Good to go (valid texture ID and loaded bitmap...
	// Now set the texture...
	//glActiveTexture( textureUnit );	// GL_TEXTURE0, GL_TEXTURE1, etc.
	glBindTexture(GL_TEXTURE_2D, this->m_textureNumber);
#if 1
	glTexImage2D( GL_TEXTURE_2D,		// target (2D, 3D, etc.)
				 0,					// MIP map level
				 GL_RGBA,			// internal format
				 this->m_numberOfColumns,	// width (pixels)
				 this->m_numberOfRows,	// height (pixels)
				 0,					// border (0 or 1)
				 GL_RGB,			// format of pixel data
				 GL_UNSIGNED_BYTE,	// type of pixel data
				 this->m_p_theImages);	// pointer to data in memory
	if (this->bWasThereAnOpenGLError()) { return false; }
#else
	glTexStorage2D(GL_TEXTURE_2D,
		            0,
					GL_RGB,
					this->m_numberOfColumns,
					this->m_numberOfRows);

	if ( this->bWasThereAnOpenGLError() )	{ return false;	}

	//for ( int index = 0; index != 400; index++ )
	//{
	//	std::cout << (int)this->m_p_theImages[index].redPixel << ", ";
	//	std::cout << (int)this->m_p_theImages[index].greenPixel << ", ";
	//	std::cout << (int)this->m_p_theImages[index].bluePixel << std::endl;
	//}

//	glTextureSubImage2D(
	glTexSubImage2D( GL_TEXTURE_2D,
		             0,		// Level 0
					 0, 0,	// Offset of 0,0
					 this->m_numberOfColumns,
					 this->m_numberOfRows,
					 GL_RGB,			// Pixel data format
					 GL_UNSIGNED_BYTE,	// Pixel data type
					 this->m_p_theImages );

	if ( this->bWasThereAnOpenGLError() )	{ return false;	}
#endif

	this->ClearBMP();

	if ( bGenerateMIPMap )
	{
		glGenerateMipmap( GL_TEXTURE_2D );		// OpenGL 4.0
	}

	//if ( this->bWasThereAnOpenGLError() )	{ return false;	}

	//glBindTexture(GL_TEXTURE_2D, m_textureNumber);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, /*GL_CLAMP*/ GL_REPEAT );
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, /*GL_CLAMP*/ GL_REPEAT );
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, /*GL_NEAREST*/ GL_LINEAR);
	//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, /*GL_NEAREST*/ GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

//	GLfloat largest_supported_anisotropy;
//	glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
//	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);

	//if ( this->bWasThereAnOpenGLError() )	{ return false;	}

	//this->m_textureUnit = textureUnit;

	this->m_bIs2DTexture = true;

	//glBindTexture(GL_TEXTURE_2D, 0);

	return bReturnVal;
}

bool CTextureFromBMP::CreateNewCubeTextureFromBMPFiles(std::string cubeMapName, std::string fileNameFullPath)
{

	bool bReturnVal = true;

	// Do the magic...

	// Pick a texture number...
	//GLuint textureNum = 0;
	glGenTextures(1, &(this->m_textureNumber));
	// Worked?
	if ((glGetError() & GL_INVALID_VALUE) == GL_INVALID_VALUE)
	{
		bReturnVal = false;
		return false;
	}

	//
	//glEnable(GL_TEXTURE_2D);
	//glActiveTexture( textureUnit );	// GL_TEXTURE0, GL_TEXTURE1, etc.
	glBindTexture(GL_TEXTURE_CUBE_MAP, this->m_textureNumber);

	//glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);

	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE /*GL_REPEAT*/);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE /*GL_REPEAT*/);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE /*GL_REPEAT*/);

	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	// IF YOU DON'T GENERATE MIP MAPS, then you can use LINEAR filtering
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	//glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );

	//if (bIsSeamless)
	//{
	//	glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);	// OpenGL 4.1, maybe
	//}

	//if (this->bWasThereAnOpenGLError(errorEnum, errorString, errorDetails)) { return false; }

	// Positive X image...
	// Assume all the images are the same size. If not, then it will screw up
	if (this->LoadBMP(fileNameFullPath))
	{
		glTexImage2D(GL_TEXTURE_CUBE_MAP,		// target (2D, 3D, etc.)
			0,					// MIP map level
			GL_RGB,			// internal format
			this->m_numberOfColumns,	// width (pixels)
			this->m_numberOfRows,	// height (pixels)
			0,					// border (0 or 1)
			GL_RGB,			// format of pixel data
			GL_UNSIGNED_BYTE,	// type of pixel data
			this->m_p_theImages);	// pointer to data in memory
		if (this->bWasThereAnOpenGLError()) { return false; }
	}
	else
	{
		this->m_lastErrorNum = CTextureFromBMP::ERORR_FILE_WONT_OPEN;
		return false;
	}

	this->m_textureName = cubeMapName;

	//this->m_textureUnit = textureUnit;

	this->m_bIsCubeMap = true;

	// End of Do the magic...

	return bReturnVal;
}

bool CTextureFromBMP::CreateNewCubeTextureFromBMPFiles(std::string cubeMapName,
	std::string posX_fileName, std::string negX_fileName,
	std::string posY_fileName, std::string negY_fileName,
	std::string posZ_fileName, std::string negZ_fileName,
	/*GLenum textureUnit, */bool bIsSeamless,
	GLenum &errorEnum, std::string &errorString, std::string &errorDetails)
{

	bool bReturnVal = true;

	// Do the magic...

	// Pick a texture number...
	//GLuint textureNum = 0;
	glGenTextures(1, &(this->m_textureNumber));
	// Worked?
	if ((glGetError() & GL_INVALID_VALUE) == GL_INVALID_VALUE)
	{
		bReturnVal = false;
		return false;
	}

	//
	//glEnable(GL_TEXTURE_2D);
	//glActiveTexture( textureUnit );	// GL_TEXTURE0, GL_TEXTURE1, etc.
	glBindTexture(GL_TEXTURE_CUBE_MAP, this->m_textureNumber);

	//glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);

	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE /*GL_REPEAT*/);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE /*GL_REPEAT*/);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE /*GL_REPEAT*/);

	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	// IF YOU DON'T GENERATE MIP MAPS, then you can use LINEAR filtering
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	//glTexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );

	if (bIsSeamless)
	{
		glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);	// OpenGL 4.1, maybe
	}

	if (this->bWasThereAnOpenGLError(errorEnum, errorString, errorDetails)) { return false; }

	// Positive X image...
	// Assume all the images are the same size. If not, then it will screw up
	if (this->LoadBMP(posX_fileName))
	{
		glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X,		// target (2D, 3D, etc.)
			0,					// MIP map level
			GL_RGBA,			// internal format
			this->m_numberOfColumns,	// width (pixels)
			this->m_numberOfRows,	// height (pixels)
			0,					// border (0 or 1)
			GL_RGB,			// format of pixel data
			GL_UNSIGNED_BYTE,	// type of pixel data
			this->m_p_theImages);	// pointer to data in memory
		this->ClearBMP();
		if (this->bWasThereAnOpenGLError()) { return false; }
	}
	this->ClearBMP();
	if (this->bWasThereAnOpenGLError(errorEnum, errorString, errorDetails)) { return false; }

	// Negative X image...
	if (this->LoadBMP(negX_fileName))
	{
		glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X,		// target (2D, 3D, etc.)
			0,					// MIP map level
			GL_RGBA,			// internal format
			this->m_numberOfColumns,	// width (pixels)
			this->m_numberOfRows,	// height (pixels)
			0,					// border (0 or 1)
			GL_RGB,			// format of pixel data
			GL_UNSIGNED_BYTE,	// type of pixel data
			this->m_p_theImages);	// pointer to data in memory
		this->ClearBMP();
		if (this->bWasThereAnOpenGLError()) { return false; }
	}
	else
	{
		this->m_lastErrorNum = CTextureFromBMP::ERORR_FILE_WONT_OPEN;
		return false;
	}

	// Positive Y image...
	if (this->LoadBMP(posY_fileName))
	{
		glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,		// target (2D, 3D, etc.)
			0,					// MIP map level
			GL_RGBA,			// internal format
			this->m_numberOfColumns,	// width (pixels)
			this->m_numberOfRows,	// height (pixels)
			0,					// border (0 or 1)
			GL_RGB,			// format of pixel data
			GL_UNSIGNED_BYTE,	// type of pixel data
			this->m_p_theImages);	// pointer to data in memory
		this->ClearBMP();
		if (this->bWasThereAnOpenGLError()) { return false; }
	}
	else
	{
		this->m_lastErrorNum = CTextureFromBMP::ERORR_FILE_WONT_OPEN;
		return false;
	}

	// Negative Y image...
	if (this->LoadBMP(negY_fileName))
	{
		glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,		// target (2D, 3D, etc.)
			0,					// MIP map level
			GL_RGBA,			// internal format
			this->m_numberOfColumns,	// width (pixels)
			this->m_numberOfRows,	// height (pixels)
			0,					// border (0 or 1)
			GL_RGB,			// format of pixel data
			GL_UNSIGNED_BYTE,	// type of pixel data
			this->m_p_theImages);	// pointer to data in memory
		this->ClearBMP();
		if (this->bWasThereAnOpenGLError()) { return false; }
	}
	else
	{
		this->m_lastErrorNum = CTextureFromBMP::ERORR_FILE_WONT_OPEN;
		return false;
	}

	// Positive Z image...
	if (this->LoadBMP(posZ_fileName))
	{
		glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z,		// target (2D, 3D, etc.)
			0,					// MIP map level
			GL_RGBA,			// internal format
			this->m_numberOfColumns,	// width (pixels)
			this->m_numberOfRows,	// height (pixels)
			0,					// border (0 or 1)
			GL_RGB,			// format of pixel data
			GL_UNSIGNED_BYTE,	// type of pixel data
			this->m_p_theImages);	// pointer to data in memory
		this->ClearBMP();
		if (this->bWasThereAnOpenGLError()) { return false; }
	}
	else
	{
		this->m_lastErrorNum = CTextureFromBMP::ERORR_FILE_WONT_OPEN;
		return false;
	}

	// Negative Z image...
	if (this->LoadBMP(negZ_fileName))
	{
		glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,		// target (2D, 3D, etc.)
			0,					// MIP map level
			GL_RGBA,			// internal format
			this->m_numberOfColumns,	// width (pixels)
			this->m_numberOfRows,	// height (pixels)
			0,					// border (0 or 1)
			GL_RGB,			// format of pixel data
			GL_UNSIGNED_BYTE,	// type of pixel data
			this->m_p_theImages);	// pointer to data in memory
		this->ClearBMP();
		if (this->bWasThereAnOpenGLError()) { return false; }
	}
	else
	{
		this->m_lastErrorNum = CTextureFromBMP::ERORR_FILE_WONT_OPEN;
		return false;
	}

	this->m_textureName = cubeMapName;

	//this->m_textureUnit = textureUnit;

	this->m_bIsCubeMap = true;

	// End of Do the magic...

	return bReturnVal;
}

// Same but generates a texture number automatically
bool CTextureFromBMP::CreateNewTextureFromBMPFile( std::string textureName, std::string fileNameFullPath /*, GLenum textureUnit*/ )
{
	bool bReturnVal = true;

	// Pick a texture number...
	GLuint textureNum = 0;
	glGenTextures( 1, &(this->m_textureNumber) );
	// Worked?
	if ( ( glGetError() & GL_INVALID_VALUE ) == GL_INVALID_VALUE )
	{
		bReturnVal = false;
		return false;
	}

	//
	// Read a 24 bit bitmap from a file and save it to an arrau
	std::ifstream theFile;
	// Indicate we are reading...
#ifdef DEBUG_MODE_BITMAPREAD
	std::cout << "Reading texture file: " << fileName;
#endif
	// Note: This is set to binary mode - i.e. read the chars (bytes) as
	//	binary - set in the ios_base (i/o stream base class 'openmode' setting.
	theFile.open(fileNameFullPath.c_str(), std::ios_base::binary);
	// Did it open?
	if (!theFile)
	{
		bReturnVal = false;
		this->m_lastErrorNum = CTextureFromBMP::ERORR_FILE_WONT_OPEN;
	}
	else
	{	// File openned. Now read it.
		char letter1, letter2;
		letter1 = ReadAByte(theFile);
		letter2 = ReadAByte(theFile);
		if ((letter1 != 'B') && (letter2 != 'M'))
		{
			bReturnVal = false;
			this->m_lastErrorNum = CTextureFromBMP::ERROR_NOT_A_BMP_FILE;
		}
		else
		{	// File is BMP
			this->m_FileSize = ReadAnUnsignedLong(theFile);
			this->m_reserved1 = ReadAnUnsignedShort(theFile);
			this->m_reserved2 = ReadAnUnsignedShort(theFile);
			this->m_offsetInBits = ReadAnUnsignedLong(theFile);
            this->m_headerSize = ReadAnUnsignedLong(theFile);
            this->m_numberOfRows = ReadAnUnsignedLong(theFile);
			this->m_Height = m_OriginalHeight = m_numberOfRows;
            this->m_numberOfColumns = ReadAnUnsignedLong(theFile);
			this->m_Width = m_OriginalWidth = m_numberOfColumns;
            this->m_numberOfPlanes = ReadAnUnsignedShort(theFile);
            this->m_bitPerPixel = ReadAnUnsignedShort(theFile);
			// Is is a 24 bit bitmap?
			if (this->m_bitPerPixel != 24)
			{
				bReturnVal = false;
				this->m_lastErrorNum = CTextureFromBMP::ERROR_NOT_A_24_BIT_BITMAP;
			}
			else
			{	// It's a 24 bit bitmap...
				this->m_compressionMode = ReadAnUnsignedLong(theFile);
				this->m_imageSizeInBytes = ReadAnUnsignedLong(theFile);
				this->m_PixelsPerMeterX = ReadAnUnsignedLong(theFile);
				this->m_PixelsPerMeterY = ReadAnUnsignedLong(theFile);
				this->m_numberOfLookUpTableEntries = ReadAnUnsignedLong(theFile);
				this->m_numberOfImportantColours = ReadAnUnsignedLong(theFile);
				//
				long bytesPerRow = ((3 * m_numberOfRows + 3) / 4) * 4;
				long numberOfPaddingBytes = bytesPerRow - 3 * m_numberOfColumns;
				// Allocate enough space...
				this->m_p_theImages = new C24BitBMPpixel[m_numberOfRows * m_numberOfColumns];
				//m_p_theImages = new C32BitBMPpixel[m_numberOfRows * m_numberOfColumns];
				// Did we run out of memory?
				if (!this->m_p_theImages)
				{
					bReturnVal = false;
					m_lastErrorNum = CTextureFromBMP::ERROR_NOT_ENOUGHT_MEMORY_FOR_BITMAP;
				}
				else
				{	// Read the bitmap into memory...
					double bytesRead = 0;
					double totalBytesInFile = m_numberOfRows * m_numberOfColumns;
					long pixelCount = 0;
					for (unsigned long row = 0; row < m_numberOfRows; row++)
					{
#ifdef DEBUG_MODE_BITMAPREAD
						std::cout << "Row:" << row << std::endl;
#endif
						for (unsigned long col = 0; col < m_numberOfColumns; col++)
						{
							char thered, thegreen, theblue;
							thered = theblue = thegreen = 0;
							theFile.get(theblue);
							theFile.get(thegreen);
							theFile.get(thered);
							this->m_p_theImages[pixelCount].redPixel = static_cast<unsigned char>(thered);
							this->m_p_theImages[pixelCount].greenPixel = static_cast<unsigned char>(thegreen);
							this->m_p_theImages[pixelCount].bluePixel = static_cast<unsigned char>(theblue);
							//m_p_theImages[pixelCount].alphaPixel = 255;

#ifdef DEBUG_MODE_BITMAPREAD
							std::cout << (static_cast<unsigned int>(thered) & 0x00FF) << ", ";
							std::cout << (static_cast<unsigned int>(thegreen) & 0x00FF) << ", ";
							std::cout << (static_cast<unsigned int>(theblue) & 0x00FF) << "\t";
#endif
							pixelCount++;
							bytesRead += 3;	// Add three bytes
						}
#ifdef DEBUG_MODE_BITMAPREAD
						std::cout << std::endl;
#endif
						// We are at the end of the row and there will
						//	still be bytes padding up to a multiple of 4...
						// Read and discard these...
						for (int discardedBytes = 0; discardedBytes < numberOfPaddingBytes; discardedBytes++)
						{
							char tempChar;
							theFile >> tempChar;
						}
						// How much have we read?
						// NOTE: This really isn't percent, but it does the job of
						//	printing out fewer dots.
						int percentRead = static_cast<int>( (static_cast<double>(bytesRead) / static_cast<double>(totalBytesInFile)) * 100);
						if ((percentRead % 25) == 0)
						{
#ifdef DEBUG_MODE_BITMAPREAD
							std::cout << ".";
#endif
						}
					}
#ifdef DEBUG_MODE_BITMAPREAD
					std::cout << "complete." << std::endl;

#endif
					// BMP file is read....

					// Now set the texture...
					glBindTexture(GL_TEXTURE_2D, m_textureNumber);
					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, /*GL_CLAMP*/ GL_REPEAT );
					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, /*GL_CLAMP*/ GL_REPEAT );
					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, /*GL_NEAREST*/ GL_LINEAR);
					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, /*GL_NEAREST*/ GL_LINEAR);
					glTexImage2D( GL_TEXTURE_2D,		// target (2D, 3D, etc.)
								 0,					// MIP map level
								 GL_RGBA,			// internal format
								 m_numberOfColumns,	// width (pixels)
								 m_numberOfRows,	// height (pixels)
								 0,					// border (0 or 1)
								 GL_RGB,			// format of pixel data
								 GL_UNSIGNED_BYTE,	// type of pixel data
								 m_p_theImages);	// pointer to data in memory
					glBindTexture(GL_TEXTURE_2D, m_textureNumber);

					this->m_bIs2DTexture = true;

				} // if (!m_p_theImages) // Run out of memory?
			} // if (m_bitPerPixel != 24) // Not a 24 bit bitmap
		} // if ((letter1 != 'B') && (letter2 != 'M'))	// Not a bitmap file...
		// Close the file
		theFile.close();
		delete [] this->m_p_theImages;
	} // if (!theFile)   // Did the file open?

	this->m_fileNameFullPath = fileNameFullPath;
	this->m_textureName = textureName;

	// All done.
	return bReturnVal;
}

bool CTextureFromBMP::ClearBMP( void )
{
	delete [] this->m_p_theImages;
	this->m_p_theImages = 0;
	return true;
}

// Some of this taken from: http://www.allegro.cc/forums/thread/601551
bool CTextureFromBMP::CreateNewBMPFromCurrentTexture( int mipMapLevel )
{
	GLint textureWidth, textureHeight;

	glGetTexLevelParameteriv(GL_TEXTURE_2D, mipMapLevel, GL_TEXTURE_WIDTH, &textureWidth);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, mipMapLevel, GL_TEXTURE_HEIGHT, &textureHeight);

	int numberOfPixels = textureWidth * textureHeight;

	//GLubyte *buffer = (GLubyte *)malloc(textureSize);
	//GLubyte *buffer = new GLubyte[ textureSize ];
	this->m_p_theImages = new C24BitBMPpixel[ numberOfPixels ];

	//GLubyte buffer[ 5000000 ] = {0};
	//
	glGetTexImage(GL_TEXTURE_2D, mipMapLevel, GL_RGB, GL_UNSIGNED_BYTE, this->m_p_theImages );

	// Now fill in all the BMP stuff...
	this->m_reserved1 = this->m_reserved2 = 0;
	this->m_offsetInBits = 54;	// (always 54);
	this->m_headerSize = 40;	// (always 40);
	this->m_numberOfPlanes = 1;	// (always 1);
	this->m_bitPerPixel = 24;	// (always 24);

	this->m_compressionMode = 0;	// (0);
	this->m_imageSizeInBytes = numberOfPixels * sizeof( C24BitBMPpixel );
	this->m_PixelsPerMeterX = 2880;		// Not sure why...
	this->m_PixelsPerMeterY = 2880;		// Not sure why...
	this->m_numberOfLookUpTableEntries = 0;	// Always seem to be zero.
	this->m_numberOfImportantColours = 0;	// Always seem to be zero.

	this->m_numberOfColumns = textureHeight;
	this->m_numberOfRows = textureWidth;

	long bytesPerRow = ((3 * this->m_numberOfRows + 3) / 4) * 4;
	this->m_FileSize = this->m_numberOfRows * bytesPerRow + 54;

	return true;
}

bool CTextureFromBMP::SaveBMP( std::string fileName )
{
	std::ofstream theFile;
	theFile.open( fileName.c_str(), std::ios_base::binary );
	if ( !theFile.is_open() )
	{
		return false;
	}

	//unsigned char *img = NULL;
	//int filesize = 54 + 3*w*h

	std::cout << "Writing texture to BMP" << std::endl;
	theFile << 'B' << 'M';
	this->WriteAsUnsignedLong( this->m_FileSize, theFile );	//	theFile << this->m_FileSize;
	this->WriteAsUnsignedShort( this->m_reserved1, theFile );			// 0
	this->WriteAsUnsignedShort( this->m_reserved2, theFile );			// 0
	this->WriteAsUnsignedLong( this->m_offsetInBits, theFile );			//54
	this->WriteAsUnsignedLong( this->m_headerSize, theFile );			//40
	this->WriteAsUnsignedLong( this->m_numberOfRows, theFile );
	this->WriteAsUnsignedLong( this->m_numberOfColumns, theFile );
	this->WriteAsUnsignedShort( this->m_numberOfPlanes, theFile );		// 1
	this->WriteAsUnsignedShort( this->m_bitPerPixel, theFile );			// 24
	this->WriteAsUnsignedLong( this->m_compressionMode, theFile );
	this->WriteAsUnsignedLong( this->m_imageSizeInBytes, theFile );
	this->WriteAsUnsignedLong( this->m_PixelsPerMeterX, theFile );
	this->WriteAsUnsignedLong( this->m_PixelsPerMeterY, theFile );
	this->WriteAsUnsignedLong( this->m_numberOfLookUpTableEntries, theFile );
	this->WriteAsUnsignedLong( this->m_numberOfImportantColours, theFile );

	long bytesPerRow = ((3 * this->m_numberOfRows + 3) / 4) * 4;
	long numberOfPaddingBytes = bytesPerRow - 3 * this->m_numberOfColumns;

	// Write the bitmap data to the file...
	long bytesWritten = 0;
	long totalBytesInFile = this->m_numberOfRows * this->m_numberOfColumns;
	long pixelCount = 0;

	for (unsigned long row = 0; row < this->m_numberOfRows; row++)
	{
#ifdef DEBUG_MODE_BITMAPREAD
		std::cout << "Row:" << row << std::endl;
#endif
		for (unsigned long col = 0; col < this->m_numberOfColumns; col++)
		{
			char thered   = static_cast<unsigned char>( this->m_p_theImages[pixelCount].redPixel );
			char thegreen = static_cast<unsigned char>( this->m_p_theImages[pixelCount].greenPixel );
			char theblue  = static_cast<unsigned char>( this->m_p_theImages[pixelCount].bluePixel );
			theFile.put(theblue);
			theFile.put(thegreen);
			theFile.put(thered);

			pixelCount++;
			bytesWritten += 3;	// Add three bytes
		}
#ifdef DEBUG_MODE_BITMAPREAD
		std::cout << std::endl;
#endif
		// We are at the end of the row and there will
		//	still be bytes padding up to a multiple of 4...
		// Write thes padding bytes here...
		for (int discardedBytes = 0; discardedBytes < numberOfPaddingBytes; discardedBytes++)
		{
			char tempChar = 0;
			theFile.put( tempChar );
		}
	}

	theFile.close();
	return true;
}

// These are used to read the data from a file (LoadBMP2 method).
// * index is incremented appropriate amount (to next char)
// * no bounds checking for array
char CTextureFromBMP::ReadNextChar(char* data, unsigned long &index)
{
	char returnVal = static_cast<unsigned char>(data[index]);
	index++;
	return returnVal;
}

unsigned short CTextureFromBMP::ReadNextUnsignedShort(char* data, unsigned long &index)
{
	unsigned short usTheReturnVal = 0;
	usTheReturnVal = this->ShiftAndAdd_Byte_to_UShort(usTheReturnVal, static_cast<unsigned char>(data[index]), 0);
	index++;
	usTheReturnVal = this->ShiftAndAdd_Byte_to_UShort(usTheReturnVal, static_cast<unsigned char>(data[index]), 1);
	index++;
	return usTheReturnVal;
}

unsigned long CTextureFromBMP::ReadNextUnsignedLong(char* data, unsigned long &index)
{
	unsigned long ulTheReturnVal = 0;
	// Read four bytes, but return them in reverse order.
	ulTheReturnVal = this->ShiftAndAdd_Byte_to_ULong(ulTheReturnVal, static_cast<unsigned char>(data[index]), 0);
	index++;
	ulTheReturnVal = this->ShiftAndAdd_Byte_to_ULong(ulTheReturnVal, static_cast<unsigned char>(data[index]), 1);
	index++;
	ulTheReturnVal = this->ShiftAndAdd_Byte_to_ULong(ulTheReturnVal, static_cast<unsigned char>(data[index]), 2);
	index++;
	ulTheReturnVal = this->ShiftAndAdd_Byte_to_ULong(ulTheReturnVal, static_cast<unsigned char>(data[index]), 3);
	index++;
	return ulTheReturnVal;
}

// Loads it in one "go" instead of streaming it
bool CTextureFromBMP::LoadBMP2( std::string fileName )
{
	std::ifstream theFile;
	if ( this->m_bHave_cout_output )
	{
		std::cout << "Reading texture file: " << fileName;
	}
	theFile.open(fileName.c_str(), std::ios_base::binary);
	if ( !theFile )
	{
		this->m_lastErrorNum = CTextureFromBMP::ERORR_FILE_WONT_OPEN;
		return false;
	}
	// Scan to the end to get the size
	theFile.seekg(0, std::ios::end);
	std::ios::pos_type fileSize = theFile.tellg();
	// Return to start
	theFile.seekg(0, std::ios::beg);

	char* pRawData = new char[ static_cast<unsigned int>(fileSize) ];

	theFile.read( pRawData, fileSize );
	theFile.close();

	// Now go through and decode the BMP file.
	unsigned long curIndex = 0;
	char letter1 = this->ReadNextChar( pRawData, curIndex );
	char letter2 = this->ReadNextChar( pRawData, curIndex );
	if ((letter1 != 'B') && (letter2 != 'M'))
	{
		this->m_lastErrorNum = CTextureFromBMP::ERROR_NOT_A_BMP_FILE;
		return false;
	}
	// File is BMP
	this->m_FileSize = this->ReadNextUnsignedLong(pRawData, curIndex);
	this->m_reserved1 = this->ReadNextUnsignedShort(pRawData, curIndex);
	this->m_reserved2 = this->ReadNextUnsignedShort(pRawData, curIndex);
	this->m_offsetInBits = this->ReadNextUnsignedLong(pRawData, curIndex);
    this->m_headerSize = this->ReadNextUnsignedLong(pRawData, curIndex);
    this->m_numberOfRows = this->ReadNextUnsignedLong(pRawData, curIndex);
	this->m_Height = this->m_OriginalHeight = this->m_numberOfRows;
    this->m_numberOfColumns = this->ReadNextUnsignedLong(pRawData, curIndex);
	this->m_Width = this->m_OriginalWidth = this->m_numberOfColumns;
    this->m_numberOfPlanes = this->ReadNextUnsignedShort(pRawData, curIndex);
    this->m_bitPerPixel = this->ReadNextUnsignedShort(pRawData, curIndex);
	// Is is a 24 bit bitmap?
	if (this->m_bitPerPixel != 24)
	{
		this->m_lastErrorNum = CTextureFromBMP::ERROR_NOT_A_24_BIT_BITMAP;
		return false;
	}

	this->m_compressionMode = this->ReadNextUnsignedLong(pRawData, curIndex);
	this->m_imageSizeInBytes = this->ReadNextUnsignedLong(pRawData, curIndex);
	this->m_PixelsPerMeterX = this->ReadNextUnsignedLong(pRawData, curIndex);
	this->m_PixelsPerMeterY = this->ReadNextUnsignedLong(pRawData, curIndex);
	this->m_numberOfLookUpTableEntries = this->ReadNextUnsignedLong(pRawData, curIndex);
	this->m_numberOfImportantColours = this->ReadNextUnsignedLong(pRawData, curIndex);

	//
	long bytesPerRow = ((3 * this->m_numberOfRows + 3) / 4) * 4;
	long numberOfPaddingBytes = bytesPerRow - 3 * this->m_numberOfColumns;

	// Allocate enough space...
	this->m_p_theImages = new C24BitBMPpixel[this->m_numberOfRows * this->m_numberOfColumns];

	// Did we run out of memory?
	if (!this->m_p_theImages)
	{
		this->m_lastErrorNum = CTextureFromBMP::ERROR_NOT_ENOUGHT_MEMORY_FOR_BITMAP;
		return false;
	}

	// Read the bitmap into memory...
	unsigned long bytesRead = 0;
	unsigned long totalBytesInFile = this->m_numberOfRows * this->m_numberOfColumns;
	unsigned long pixelCount = 0;

	for (unsigned long row = 0; row < m_numberOfRows; row++)
	{
		for (unsigned long col = 0; col < m_numberOfColumns; col++)
		{
			char theblue = this->ReadNextChar(pRawData, curIndex);
			char thegreen = this->ReadNextChar(pRawData, curIndex);
			char thered = this->ReadNextChar(pRawData, curIndex);

			this->m_p_theImages[pixelCount].redPixel = static_cast<unsigned char>(thered);
			this->m_p_theImages[pixelCount].greenPixel = static_cast<unsigned char>(thegreen);
			this->m_p_theImages[pixelCount].bluePixel = static_cast<unsigned char>(theblue);
							//m_p_theImages[pixelCount].alphaPixel = 255;

#ifdef DEBUG_MODE_BITMAPREAD
			std::cout << (static_cast<unsigned int>(thered) & 0x00FF) << ", ";
			std::cout << (static_cast<unsigned int>(thegreen) & 0x00FF) << ", ";
			std::cout << (static_cast<unsigned int>(theblue) & 0x00FF) << "\t";
#endif
			pixelCount++;
			bytesRead += 3;	// Add three bytes
		}// for (unsigned long col
#ifdef DEBUG_MODE_BITMAPREAD
		std::cout << std::endl;
#endif
		// We are at the end of the row and there will
		//	still be bytes padding up to a multiple of 4...
		// Read and discard these...
		for (int discardedBytes = 0; discardedBytes < numberOfPaddingBytes; discardedBytes++)
		{
			char tempChar = this->ReadNextChar(pRawData, curIndex);
		}
		// How much have we read?
		// NOTE: This really isn't percent, but it does the job of
		//	printing out fewer dots.
		int percentRead = static_cast<int>( (static_cast<double>(bytesRead) / static_cast<double>(totalBytesInFile)) * 100);
		if ((percentRead % 25) == 0)
		{
			if ( this->m_bHave_cout_output )
			{
				std::cout << ".";
			}
		}
	}// for (unsigned long row...
	if ( this->m_bHave_cout_output )
	{
		std::cout << "complete." << std::endl;
	}
	// BMP file is read....

	return true;
}

// When done, this->m_p_theImages contains a valid, loaded 24 bit BMP.
bool CTextureFromBMP::LoadBMP( std::string fileName )
{
	bool bReturnVal = true;

	//
	// Read a 24 bit bitmap from a file and save it to an arrau
	std::ifstream theFile;
	// Indicate we are reading...
	if ( this->m_bHave_cout_output )
	{
		std::cout << "Reading texture file: " << fileName;
	}
	// Note: This is set to binary mode - i.e. read the chars (bytes) as
	//	binary - set in the ios_base (i/o stream base class 'openmode' setting.
	theFile.open(fileName.c_str(), std::ios_base::binary);
	// Did it open?
	if (!theFile)
	{
		bReturnVal = false;
		this->m_lastErrorNum = CTextureFromBMP::ERORR_FILE_WONT_OPEN;
	}
	else
	{	// File openned. Now read it.
		char letter1, letter2;
		letter1 = ReadAByte(theFile);
		letter2 = ReadAByte(theFile);
		if ((letter1 != 'B') && (letter2 != 'M'))
		{
			bReturnVal = false;
			this->m_lastErrorNum = CTextureFromBMP::ERROR_NOT_A_BMP_FILE;
		}
		else
		{	// File is BMP
			this->m_FileSize = ReadAnUnsignedLong(theFile);
			this->m_reserved1 = ReadAnUnsignedShort(theFile);
			this->m_reserved2 = ReadAnUnsignedShort(theFile);
			this->m_offsetInBits = ReadAnUnsignedLong(theFile);
            this->m_headerSize = ReadAnUnsignedLong(theFile);
            this->m_numberOfRows = ReadAnUnsignedLong(theFile);
			this->m_Height = m_OriginalHeight = m_numberOfRows;
            this->m_numberOfColumns = ReadAnUnsignedLong(theFile);
			this->m_Width = m_OriginalWidth = m_numberOfColumns;
            this->m_numberOfPlanes = ReadAnUnsignedShort(theFile);
            this->m_bitPerPixel = ReadAnUnsignedShort(theFile);
			// Is is a 24 bit bitmap?
			if (this->m_bitPerPixel != 24)
			{
				bReturnVal = false;
				this->m_lastErrorNum = CTextureFromBMP::ERROR_NOT_A_24_BIT_BITMAP;
			}
			else
			{	// It's a 24 bit bitmap...
				this->m_compressionMode = ReadAnUnsignedLong(theFile);
				this->m_imageSizeInBytes = ReadAnUnsignedLong(theFile);
				this->m_PixelsPerMeterX = ReadAnUnsignedLong(theFile);
				this->m_PixelsPerMeterY = ReadAnUnsignedLong(theFile);
				this->m_numberOfLookUpTableEntries = ReadAnUnsignedLong(theFile);
				this->m_numberOfImportantColours = ReadAnUnsignedLong(theFile);
				//
				long bytesPerRow = ((3 * m_numberOfRows + 3) / 4) * 4;
				long numberOfPaddingBytes = bytesPerRow - 3 * m_numberOfColumns;
				// Allocate enough space...
				this->m_p_theImages = new C24BitBMPpixel[m_numberOfRows * m_numberOfColumns];
				//m_p_theImages = new C32BitBMPpixel[m_numberOfRows * m_numberOfColumns];
				// Did we run out of memory?
				if (!this->m_p_theImages)
				{
					bReturnVal = false;
					m_lastErrorNum = CTextureFromBMP::ERROR_NOT_ENOUGHT_MEMORY_FOR_BITMAP;
				}
				else
				{	// Read the bitmap into memory...
					double bytesRead = 0;
					double totalBytesInFile = m_numberOfRows * m_numberOfColumns;
					long pixelCount = 0;
					for (unsigned long row = 0; row < m_numberOfRows; row++)
					{
#ifdef DEBUG_MODE_BITMAPREAD
						std::cout << "Row:" << row << std::endl;
#endif
						for (unsigned long col = 0; col < m_numberOfColumns; col++)
						{
							char thered, thegreen, theblue;
							thered = theblue = thegreen = 0;
							theFile.get(theblue);
							theFile.get(thegreen);
							theFile.get(thered);
							this->m_p_theImages[pixelCount].redPixel = static_cast<unsigned char>(thered);
							this->m_p_theImages[pixelCount].greenPixel = static_cast<unsigned char>(thegreen);
							this->m_p_theImages[pixelCount].bluePixel = static_cast<unsigned char>(theblue);
							//m_p_theImages[pixelCount].alphaPixel = 255;

#ifdef DEBUG_MODE_BITMAPREAD
							std::cout << (static_cast<unsigned int>(thered) & 0x00FF) << ", ";
							std::cout << (static_cast<unsigned int>(thegreen) & 0x00FF) << ", ";
							std::cout << (static_cast<unsigned int>(theblue) & 0x00FF) << "\t";
#endif
							pixelCount++;
							bytesRead += 3;	// Add three bytes
						}
#ifdef DEBUG_MODE_BITMAPREAD
						std::cout << std::endl;
#endif
						// We are at the end of the row and there will
						//	still be bytes padding up to a multiple of 4...
						// Read and discard these...
						for (int discardedBytes = 0; discardedBytes < numberOfPaddingBytes; discardedBytes++)
						{
							char tempChar;
							theFile >> tempChar;
						}
						// How much have we read?
						// NOTE: This really isn't percent, but it does the job of
						//	printing out fewer dots.
						int percentRead = static_cast<int>( (static_cast<double>(bytesRead) / static_cast<double>(totalBytesInFile)) * 100);
						if ((percentRead % 25) == 0)
						{
							if ( this->m_bHave_cout_output )
							{
								std::cout << ".";
							}
						}
					}
					if ( this->m_bHave_cout_output )
					{
						std::cout << "complete." << std::endl;
					}
					// BMP file is read....

					//// Now set the texture...
					//glBindTexture(GL_TEXTURE_2D, m_textureNumber);
					//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, /*GL_CLAMP*/ GL_REPEAT );
					//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, /*GL_CLAMP*/ GL_REPEAT );
					//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, /*GL_NEAREST*/ GL_LINEAR);
					//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, /*GL_NEAREST*/ GL_LINEAR);
					//glTexImage2D( GL_TEXTURE_2D,		// target (2D, 3D, etc.)
					//			 0,					// MIP map level
					//			 GL_RGBA,			// internal format
					//			 m_numberOfColumns,	// width (pixels)
					//			 m_numberOfRows,	// height (pixels)
					//			 0,					// border (0 or 1)
					//			 GL_RGB,			// format of pixel data
					//			 GL_UNSIGNED_BYTE,	// type of pixel data
					//			 m_p_theImages);	// pointer to data in memory
					//glBindTexture(GL_TEXTURE_2D, m_textureNumber);

				} // if (!m_p_theImages) // Run out of memory?
			} // if (m_bitPerPixel != 24) // Not a 24 bit bitmap
		} // if ((letter1 != 'B') && (letter2 != 'M'))	// Not a bitmap file...
		// Close the file
		theFile.close();
	} // if (!theFile)   // Did the file open?

	// All done.
	return bReturnVal;
}

////  ____                _       _   _               _____         _                  _____                    ____  __  __ ____  _____ _ _
//// / ___|_ __ ___  __ _| |_ ___| \ | | _____      _|_   _|____  _| |_ _   _ _ __ ___|  ___| __ ___  _ __ ___ | __ )|  \/  |  _ \|  ___(_) | ___
////| |   | '__/ _ \/ _` | __/ _ \  \| |/ _ \ \ /\ / / | |/ _ \ \/ / __| | | | '__/ _ \ |_ | '__/ _ \| '_ ` _ \|  _ \| |\/| | |_) | |_  | | |/ _ \
////| |___| | |  __/ (_| | ||  __/ |\  |  __/\ V  V /  | |  __/>  <| |_| |_| | | |  __/  _|| | | (_) | | | | | | |_) | |  | |  __/|  _| | | |  __/
//// \____|_|  \___|\__,_|\__\___|_| \_|\___| \_/\_/   |_|\___/_/\_\\__|\__,_|_|  \___|_|  |_|  \___/|_| |_| |_|____/|_|  |_|_|   |_|   |_|_|\___|
////
//// Returns true if able to load texture and store it
//bool CTextureFromBMP::CreateNewTextureFromBMPFile_OLD(std::string fileName, GLuint textureNumber)
//{
//	bool bReturnVal = true;
//	//
//	// Read a 24 bit bitmap from a file and save it to an arrau
//	std::ifstream theFile;
//	// Indicate we are reading...
//	std::cout << "Reading texture file: " << fileName;
//	// Note: This is set to binary mode - i.e. read the chars (bytes) as
//	//	binary - set in the ios_base (i/o stream base class 'openmode' setting.
//	theFile.open(fileName.c_str(), std::ios_base::binary);
//	// Did it open?
//	if (!theFile)
//	{
//		bReturnVal = false;
//		m_lastErrorNum = CTextureFromBMP::ERORR_FILE_WONT_OPEN;
//	}
//	else
//	{	// File openned. Now read it.
//		char letter1, letter2;
//		letter1 = ReadAByte(theFile);
//		letter2 = ReadAByte(theFile);
//		if ((letter1 != 'B') && (letter2 != 'M'))
//		{
//			bReturnVal = false;
//			m_lastErrorNum = CTextureFromBMP::ERROR_NOT_A_BMP_FILE;
//		}
//		else
//		{	// File is BMP
//			m_FileSize = ReadAnUnsignedLong(theFile);
//			m_reserved1 = ReadAnUnsignedShort(theFile);
//			m_reserved2 = ReadAnUnsignedShort(theFile);
//			m_offsetInBits = ReadAnUnsignedLong(theFile);
//            m_headerSize = ReadAnUnsignedLong(theFile);
//            m_numberOfRows = ReadAnUnsignedLong(theFile);
//			m_Height = m_OriginalHeight = m_numberOfRows;
//            m_numberOfColumns = ReadAnUnsignedLong(theFile);
//			m_Width = m_OriginalWidth = m_numberOfColumns;
//            m_numberOfPlanes = ReadAnUnsignedShort(theFile);
//            m_bitPerPixel = ReadAnUnsignedShort(theFile);
//			// Is is a 24 bit bitmap?
//			if (m_bitPerPixel != 24)
//			{
//				bReturnVal = false;
//				m_lastErrorNum = CTextureFromBMP::ERROR_NOT_A_24_BIT_BITMAP;
//			}
//			else
//			{	// It's a 24 bit bitmap...
//				m_compressionMode = ReadAnUnsignedLong(theFile);
//				m_imageSizeInBytes = ReadAnUnsignedLong(theFile);
//				m_PixelsPerMeterX = ReadAnUnsignedLong(theFile);
//				m_PixelsPerMeterY = ReadAnUnsignedLong(theFile);
//				m_numberOfLookUpTableEntries = ReadAnUnsignedLong(theFile);
//				m_numberOfImportantColours = ReadAnUnsignedLong(theFile);
//				//
//				long bytesPerRow = ((3 * m_numberOfRows + 3) / 4) * 4;
//				//long bytesPerRow = ((4 * m_numberOfRows + 4) / 4) * 4;
//				long numberOfPaddingBytes = bytesPerRow - 3 * m_numberOfColumns;
//				//long numberOfPaddingBytes = bytesPerRow - 4 * m_numberOfColumns;
//				// Allocate enough space...
//				m_p_theImages = new C24BitBMPpixel[m_numberOfRows * m_numberOfColumns];
//				//m_p_theImages = new C32BitBMPpixel[m_numberOfRows * m_numberOfColumns];
//				// Did we run out of memory?
//				if (!m_p_theImages)
//				{
//					bReturnVal = false;
//					m_lastErrorNum = CTextureFromBMP::ERROR_NOT_ENOUGHT_MEMORY_FOR_BITMAP;
//				}
//				else
//				{	// Read the bitmap into memory...
//					double bytesRead = 0;
//					double totalBytesInFile = m_numberOfRows * m_numberOfColumns;
//					long pixelCount = 0;
//					for (unsigned long row = 0; row < m_numberOfRows; row++)
//					{
//#ifdef DEBUG_MODE_BITMAPREAD
//						std::cout << "Row:" << row << std::endl;
//#endif
//						for (unsigned long col = 0; col < m_numberOfColumns; col++)
//						{
//							char thered, thegreen, theblue;
//							thered = theblue = thegreen = 0;
//							theFile.get(theblue);
//							theFile.get(thegreen);
//							theFile.get(thered);
//							m_p_theImages[pixelCount].redPixel = static_cast<unsigned char>(thered);
//							m_p_theImages[pixelCount].greenPixel = static_cast<unsigned char>(thegreen);
//							m_p_theImages[pixelCount].bluePixel = static_cast<unsigned char>(theblue);
//							//m_p_theImages[pixelCount].alphaPixel = 255;
//
//#ifdef DEBUG_MODE_BITMAPREAD
//							std::cout << (static_cast<unsigned int>(thered) & 0x00FF) << ", ";
//							std::cout << (static_cast<unsigned int>(thegreen) & 0x00FF) << ", ";
//							std::cout << (static_cast<unsigned int>(theblue) & 0x00FF) << "\t";
//#endif
//							pixelCount++;
//							bytesRead += 3;	// Add three bytes
//						}
//#ifdef DEBUG_MODE_BITMAPREAD
//						std::cout << std::endl;
//#endif
//						// We are at the end of the row and there will
//						//	still be bytes padding up to a multiple of 4...
//						// Read and discard these...
//						for (int discardedBytes = 0; discardedBytes < numberOfPaddingBytes; discardedBytes++)
//						{
//							char tempChar;
//							theFile >> tempChar;
//						}
//						// How much have we read?
//						// NOTE: This really isn't percent, but it does the job of
//						//	printing out fewer dots.
//						int percentRead = static_cast<int>( (static_cast<double>(bytesRead) / static_cast<double>(totalBytesInFile)) * 100);
//						if ((percentRead % 25) == 0)
//						{
//							std::cout << ".";
//						}
//					}
//					std::cout << "complete." << std::endl;
//					// BMP file is read....
//
//					// Now set the texture...
//					m_textureNumber = textureNumber;
//					glBindTexture(GL_TEXTURE_2D, m_textureNumber);
//					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, /*GL_CLAMP*/ GL_REPEAT );
//					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, /*GL_CLAMP*/ GL_REPEAT );
//					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, /*GL_NEAREST*/ GL_LINEAR);
//					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, /*GL_NEAREST*/ GL_LINEAR);
//					glTexImage2D(GL_TEXTURE_2D,		// target (2D, 3D, etc.)
//								 0,					// MIP map level
//								 GL_RGB,			// internal format
//								 //GL_RGBA,			// internal format
//								 m_numberOfColumns,	// width (pixels)
//								 m_numberOfRows,	// height (pixels)
//								 0,					// border (0 or 1)
//								 GL_RGB,			// format of pixel data
//								 //GL_RGBA,			// format of pixel data
//								 GL_UNSIGNED_BYTE,	// type of pixel data
//								 m_p_theImages);	// pointer to data in memory
//					//glBindTexture(GL_TEXTURE_2D, m_textureNumber);
//
//				} // if (!m_p_theImages) // Run out of memory?
//			} // if (m_bitPerPixel != 24) // Not a 24 bit bitmap
//		} // if ((letter1 != 'B') && (letter2 != 'M'))	// Not a bitmap file...
//		// Close the file
//		theFile.close();
//	} // if (!theFile)   // Did the file open?
//
//	// All done.
//	return bReturnVal;
//}

// __  __       _       _____         _                     _        _   _
//|  \/  | __ _| | ____|_   _|____  _| |_ _   _ _ __ ___   / \   ___| |_(_)_   _____
//| |\/| |/ _` | |/ / _ \| |/ _ \ \/ / __| | | | '__/ _ \ / _ \ / __| __| \ \ / / _ \
//| |  | | (_| |   <  __/| |  __/>  <| |_| |_| | | |  __// ___ \ (__| |_| |\ V /  __/
//|_|  |_|\__,_|_|\_\___||_|\___/_/\_\\__|\__,_|_|  \___/_/   \_\___|\__|_| \_/ \___|
//
// Returns true if texture exists and can be applied
bool CTextureFromBMP::MakeTextureActive(void)
{
	bool bReturnVal = true;
	// Check if texturing is enabled?
	GLboolean bOldTextureMode = glIsEnabled(GL_TEXTURE_2D);
	// Set the texture mode...
	if (bOldTextureMode != GL_FALSE)
	{
		glEnable(GL_TEXTURE_2D);
	}
	// No implementation yet.
	glBindTexture(GL_TEXTURE_2D, m_textureNumber);

	// Restore the initial texture mode...
	if (bOldTextureMode != GL_TRUE)
	{
		glDisable(GL_TEXTURE_2D);
	}
	return bReturnVal;
}
// This allows you to set the GL_MODULATE, GL_DECAL, GL_BLEND, or GL_REPLACE modes
//	in OpenGL as a parameter
bool CTextureFromBMP::SetTextureEnvironmentMode(GLint textureReplacementMode)
{
	bool bReturnVal = true;
	// Is this a valid replacementMode?
	if ((textureReplacementMode != GL_MODULATE) &&
		(textureReplacementMode != GL_DECAL) &&
		(textureReplacementMode != GL_BLEND) &&
		(textureReplacementMode != GL_REPLACE))
	{
		textureReplacementMode = GL_REPLACE;
	}
#ifdef DEBUG_MODE_TEXTUREREPLACEMENT
	switch (textureReplacementMode)
	{
	case GL_MODULATE:
		std::cout << "Texture replacement mode is GL_MODULATE" << std::endl;
		break;
	case GL_DECAL:
		std::cout << "Texture replacement mode is GL_DECAL" << std::endl;
		break;
	case GL_BLEND:
		std::cout << "Texture replacement mode is GL_BLEND" << std::endl;
		break;
	case GL_REPLACE:
		std::cout << "Texture replacement mode is GL_REPLACE" << std::endl;
		break;
	default:
		std::cout << "Unknown Texture repalcement mode" << std::endl;
		break;
	}
#endif
	// Set the environment mode...
	// First, get the mode...
	glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &m_oldTextureEnvironmentMode);
	// Set the new mode...
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, textureReplacementMode);
	return bReturnVal;
}

bool CTextureFromBMP::RestoreOldTextureEnvironmentMode(void)
{
	bool bReturnVal = true;
	// Restore the old mode...
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, m_oldTextureEnvironmentMode);
	return bReturnVal;
}

// ____          _         ____  _ _
//|  _ \ ___ ___(_)_______| __ )(_) |_ _ __ ___   __ _ _ __
//| |_) / _ Y __| |_  / _ \  _ \| | __| '_ ` _ \ / _` | '_ \
//|  _ <  __|__ \ |/ /  __/ |_) | | |_| | | | | | (_| | |_) |
//|_| \_\___|___/_/___\___|____/|_|\__|_| |_| |_|\__,_| .__/
//                                                    |_|
// This filters a bitmap into a new size (likely powers of 2 in width or height)
bool CTextureFromBMP::ResizeBitmap(int DesiredHeight, int DesiredWidth)
{
	bool bReturnVal = true;
	// No implementation yet.
	return bReturnVal;
}

// This is for error handling.
//
int CTextureFromBMP::GetLastErrorNumber(void)
{
	return m_lastErrorNum;
}
//
std::string CTextureFromBMP::DecodeLastError(int errorNum)
{
	std::string lastErrorString;
	switch (m_lastErrorNum)
	{
	case CTextureFromBMP::ERORR_FILE_WONT_OPEN:
		lastErrorString = "ERROR: File does not exist or would not open";
		break;
	case CTextureFromBMP::ERROR_NOT_A_BMP_FILE:
		lastErrorString = "ERROR: File is not a BMP file - \'BM\' tag not present";
		break;
	case CTextureFromBMP::ERROR_NOT_A_24_BIT_BITMAP:
		lastErrorString = "ERROR: Not a 24 Bit bitmap format";
		break;
	case CTextureFromBMP::ERROR_NOT_ENOUGHT_MEMORY_FOR_BITMAP:
		lastErrorString = "ERROR: Not enought memory to hold bitmap";
		break;
	case CTextureFromBMP::ERROR_NO_ERROR:
	default:
		lastErrorString = "No error";
		break;
	}
	return lastErrorString;
}

// These functions shift numbers by one, two, and three bytes.
unsigned long CTextureFromBMP::ShiftAndAdd_Byte_to_ULong(unsigned long theULong, char theByte, int bytesToShift)
{
	// Too many bytes to shift (there are only 4 bytes in a long, so max is 3)?
	if (bytesToShift > 3)
	{
		bytesToShift = 0;
	}
	unsigned short bitsToShift = bytesToShift * 8;	// 8 bits / byte.
	// Now, convert the uChar to a uLong,
	//	shift it the number of bits,
	//	then or it (add it) to the long
	unsigned char uByte = theByte;
	theULong = theULong | (static_cast<unsigned long>(uByte) << bitsToShift);
	return theULong;
}

unsigned short CTextureFromBMP::ShiftAndAdd_Byte_to_UShort(unsigned short theUShort, char theByte, int bytesToShift)
{
	// Too many bytes to shift (there is only 2 bytes in a long, so max is 1)?
	if (bytesToShift > 1)
	{
		bytesToShift = 0;
	}
	unsigned short bitsToShift = bytesToShift * 8;	// 8 bits / byte.
	// Now, convert the uChar to a uLong,
	//	shift it the number of bits,
	//	then or it (add it) to the long
	unsigned char uByte = theByte;
	theUShort = theUShort | (static_cast<unsigned long>(uByte) << bitsToShift);
	return theUShort;
}

// These are used to read the data from a file.
unsigned long CTextureFromBMP::ReadAnUnsignedLong(std::ifstream& theStream)
{
	unsigned long ulTheReturnVal = 0;
	// Read four bytes, but return them in reverse order.
	char TheByte = 0;
	theStream.get(TheByte);
	ulTheReturnVal = ShiftAndAdd_Byte_to_ULong(ulTheReturnVal, static_cast<unsigned char>(TheByte), 0);
	theStream.get(TheByte);
	ulTheReturnVal = ShiftAndAdd_Byte_to_ULong(ulTheReturnVal, static_cast<unsigned char>(TheByte), 1);
	theStream.get(TheByte);
	ulTheReturnVal = ShiftAndAdd_Byte_to_ULong(ulTheReturnVal, static_cast<unsigned char>(TheByte), 2);
	theStream.get(TheByte);
	ulTheReturnVal = ShiftAndAdd_Byte_to_ULong(ulTheReturnVal, static_cast<unsigned char>(TheByte), 3);
	return ulTheReturnVal;
}

void CTextureFromBMP::WriteAsUnsignedShort( unsigned short value, std::ofstream& theStream )
{
	// AB --> BA
	char TheByte[2] = {0};
	TheByte[1] = static_cast<char>(( value & 0xFF00 ) >> 8 );
	TheByte[0] = static_cast<char>( value & 0x00FF );

	theStream.put( TheByte[0] );
	theStream.put( TheByte[1] );
}

void CTextureFromBMP::WriteAsUnsignedLong( unsigned long value, std::ofstream& theStream )
{
	// ABCD --> DCBA
	char TheByte[4] = {0};
	TheByte[3] = static_cast<char>(( value & 0xFF000000 ) >> 24 );
	TheByte[2] = static_cast<char>(( value & 0x00FF0000 ) >> 16 );
	TheByte[1] = static_cast<char>(( value & 0x0000FF00 ) >> 8 );
	TheByte[0] = static_cast<char>( value & 0x000000FF );

	theStream.put( TheByte[0] );
	theStream.put( TheByte[1] );
	theStream.put( TheByte[2] );
	theStream.put( TheByte[3] );
}

unsigned short CTextureFromBMP::ReadAnUnsignedShort(std::ifstream& theStream)
{
	unsigned short usTheReturnVal = 0;
	// Read two bytes, but reverse the order.
	char TheByte;
	theStream.get(TheByte);
	usTheReturnVal = ShiftAndAdd_Byte_to_UShort(usTheReturnVal, TheByte, 0);
	theStream.get(TheByte);
	usTheReturnVal = ShiftAndAdd_Byte_to_UShort(usTheReturnVal, TheByte, 1);
	return usTheReturnVal;
}

char CTextureFromBMP::ReadAByte(std::ifstream& theStream)
{
	char theByte = 0;
	theStream.get(theByte);
	return theByte;
}

// ____  _           _            _____         _                     _        ____           _            ____  _ _
//|  _ \(_)___ _ __ | | __ _ _   |_   _|____  _| |_ _   _ _ __ ___   / \   ___|  _ \ __ _ ___| |_ ___ _ __| __ )(_) |_ _ __ ___   __ _ _ __
//| | | | / __| '_ \| |/ _` | | | || |/ _ \ \/ / __| | | | '__/ _ \ / _ \ / __| |_) / _` / __| __/ _ \ '__|  _ \| | __| '_ ` _ \ / _` | '_ \
//| |_| | \__ \ |_) | | (_| | |_| || |  __/>  <| |_| |_| | | |  __// ___ \\__ \  _ < (_| \__ \ ||  __/ |  | |_) | | |_| | | | | | (_| | |_) |
//|____/|_|___/ .__/|_|\__,_|\__, ||_|\___/_/\_\\__|\__,_|_|  \___/_/   \_\___/_| \_\__,_|___/\__\___|_|  |____/|_|\__|_| |_| |_|\__,_| .__/
//            |_|            |___/                                                                                |_|
// This takes the bitmap that is read and displays it on the screen
//	as a raster image. i.e. it doesn't go through the transformations,
//	etc., it just plops it on the screen at the current raster
//	location. This is like bitmap fonts.
void CTextureFromBMP::DisplayTextureAsRasterBitmap(GLfloat xOrigin, GLfloat yOrigin, GLfloat xMove, GLfloat yMove)
{
	// convert the array of structures into a bitmap array
	GLubyte* p_theBitmap = new GLubyte[m_Width * m_Height * 4];	// 4 bytes / pixel
	unsigned long arrayIndex = 0;
#ifdef DEBUG_MODE_BITMAPDISPLAY
	static bool bDisplayedOnce = false;
#endif
	// copy the data into array...
	long pixeloffset = 0;
	for (unsigned long row = 0; row < m_Width; row++)
	{
#ifdef DEBUG_MODE_BITMAPDISPLAY
		if (!bDisplayedOnce)
		{
			std::cout << "Row = " << row << std::endl;
		}
#endif
		for (unsigned long column = 0; column < m_Height; column++)
		{
			arrayIndex = (row * m_Width) + column;
			double theRow = row;
			double theCol = column;
			p_theBitmap[arrayIndex] = m_p_theImages[pixeloffset].redPixel;
			p_theBitmap[arrayIndex + 1] = m_p_theImages[pixeloffset].greenPixel;
			p_theBitmap[arrayIndex + 2] = m_p_theImages[pixeloffset].bluePixel;
			p_theBitmap[arrayIndex + 3] = 0;
			pixeloffset++;

#ifdef DEBUG_MODE_BITMAPDISPLAY
			if (!bDisplayedOnce)
			{
				std::cout << "(R:" << static_cast<unsigned int>(p_theBitmap[arrayIndex]) << ",";
				std::cout << "G:" << static_cast<unsigned int>(p_theBitmap[arrayIndex + 1]) << ",";
				std::cout << "B:" << static_cast<unsigned int>(p_theBitmap[arrayIndex + 2]) << ",";
				std::cout << "A:" << static_cast<unsigned int>(p_theBitmap[arrayIndex + 3]);
				std::cout << ")" << std::endl;
			}
#endif
			arrayIndex++;
		}
	}
#ifdef DEBUG_MODE_BITMAPDISPLAY
	if (!bDisplayedOnce)
	{
		bDisplayedOnce = true;
	}
#endif

	// Draw the image using the glDrawPixels instead of bitmap...
	glRasterPos2i(0,0);
	glPixelZoom(10, 10);
	glDrawPixels(m_Width, m_Height, GL_BGRA, GL_UNSIGNED_BYTE, p_theBitmap);

	//glBitmap(m_Width, m_Height, xOrigin, yOrigin, xMove, yMove, p_theBitmap);
	delete [] p_theBitmap;
	return;
}

bool CTextureFromBMP::bWasThereAnOpenGLError(void)
{
	GLenum errorEnum = GL_NO_ERROR;
	std::string errorString;
	std::string errorDetails;
	return this->bWasThereAnOpenGLError( errorEnum, errorString, errorDetails );
}

bool CTextureFromBMP::bWasThereAnOpenGLError(GLenum &errorEnum)
{
	std::string errorString;
	std::string errorDetails;
	return this->bWasThereAnOpenGLError( errorEnum, errorString, errorDetails );
}

bool CTextureFromBMP::bWasThereAnOpenGLError(GLenum &errorEnum, std::string &errorString)
{
	std::string errorDetails;
	return this->bWasThereAnOpenGLError( errorEnum, errorString, errorDetails );
}

// Reutn false if everything is OK
bool CTextureFromBMP::bWasThereAnOpenGLError(GLenum &errorEnum, std::string &errorString, std::string &errorDetails )
{
	errorEnum = glGetError();
	// from: https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glGetError.xml
	switch ( errorEnum )
	{
	case GL_NO_ERROR:
		errorString = "GL_NO_ERROR";
		errorDetails = "GL_NO_ERROR: No error has been recorded.";
		/******************/
		return false;
		/******************/
		break;
	case GL_INVALID_ENUM:
		errorString = "GL_INVALID_ENUM";
		errorDetails = "GL_INVALID_ENUM: An unacceptable value is specified for an enumerated argument.";
		break;
	case GL_INVALID_VALUE:
		errorString = "GL_INVALID_VALUE";
		errorDetails = "GL_INVALID_VALUE: A numeric argument is out of range.";
		break;
	case GL_INVALID_OPERATION:
		errorString = "GL_INVALID_OPERATION";
		errorDetails = "GL_INVALID_OPERATION: The specified operation is not allowed in the current state.";
		break;
	case GL_INVALID_FRAMEBUFFER_OPERATION:
		errorString = "GL_INVALID_FRAMEBUFFER_OPERATION";
		errorDetails = "GL_INVALID_FRAMEBUFFER_OPERATION: The framebuffer object is not complete.";
		break;
	case GL_OUT_OF_MEMORY:
		errorString = "GL_OUT_OF_MEMORY";
		errorDetails = "GL_OUT_OF_MEMORY: There is not enough memory left to execute the command.";
		break;
	case GL_STACK_UNDERFLOW:
		errorString = "GL_STACK_UNDERFLOW";
		errorDetails = "GL_STACK_UNDERFLOW: An attempt has been made to perform an operation that would cause an internal stack to underflow.";
		break;
	case GL_STACK_OVERFLOW:
		errorString = "GL_STACK_OVERFLOW";
		errorDetails = "GL_STACK_OVERFLOW: An attempt has been made to perform an operation that would cause an internal stack to overflow.";
		break;
	default:
		errorString = "Unknown error";
		errorDetails = "Unknown error";
		break;
	};

	std::cout << errorDetails << std::endl;

	return true;	// There -WAS- an error
}

//GLenum CTextureFromBMP::getTextureUnit(void)
//{
//	return this->m_textureUnit;
//}

bool CTextureFromBMP::getIsCubeMap(void)
{
	return this->m_bIsCubeMap;
}

bool CTextureFromBMP::getIs2DTexture(void)
{
	return this->m_bIs2DTexture;
}

// The actual image information
//C24BitBMPpixel m_p_theImages[];
unsigned long CTextureFromBMP::GetHeight(void)
{
	return m_Height;
}

unsigned long CTextureFromBMP::GetWidth(void)
{
	return m_Width;
}

unsigned long CTextureFromBMP::GetOriginalHeight(void)
{
	return m_OriginalHeight;
}

unsigned long CTextureFromBMP::GetOriginalWidth(void)
{
	return m_OriginalWidth;
}

unsigned long CTextureFromBMP::GetFileSize(void)
{
	return m_FileSize;
}

unsigned long CTextureFromBMP::GetFileSizeInBytes(void)
{
	return m_FileSize;
}

unsigned short CTextureFromBMP::GetReserved1(void)
{
	return m_reserved1;
}

unsigned short CTextureFromBMP::GetReserved2(void)
{
	return m_reserved2;
}

unsigned long CTextureFromBMP::GetImageSizeInBytes(void)
{
	return m_imageSizeInBytes;
}

unsigned long CTextureFromBMP::GetBitsPerPixel(void)
{
	return m_bitPerPixel;
}

unsigned long CTextureFromBMP::GetOffsetInBits(void)
{
	return m_offsetInBits;
}

unsigned long CTextureFromBMP::GetCompressionMode(void)
{
	return m_compressionMode;
}

unsigned long CTextureFromBMP::GetPixelsPerMeterX(void)
{
	return m_PixelsPerMeterX;
}

unsigned long CTextureFromBMP::GetPixelsPerMeterY(void)
{
	return m_PixelsPerMeterY;
}

unsigned long CTextureFromBMP::GetNumberOfLookUpTables(void)
{
	return m_numberOfLookUpTableEntries;
}

unsigned long CTextureFromBMP::GetNumberOfImportantColours(void)
{
	return m_numberOfImportantColours;
}


text:
package test.js;

import java.util.Date;

import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;

import org.siphon.common.js.JsEngineUtil;
import org.siphon.common.js.JsTypeUtil;

import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.objects.NativeFunction;
import jdk.nashorn.internal.objects.NativeObject;

public class JsNewObject {

	public static void main(String[] args) throws ScriptException {
		ScriptEngine engine = JsEngineUtil.newEngine();
	    Bindings b = engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
	    System.out.println(b.get("Object")); // gets ECMAScript "Object" constructor
	    ScriptObjectMirror objConstructor = (ScriptObjectMirror) b.get("Object");

	    Object obj = objConstructor.call(null);
	    System.out.println(obj);

	    engine.eval("Object.prototype.say = function(){print('abcd')}");

	    ScriptObjectMirror om = (ScriptObjectMirror) objConstructor.call(null);
	    om.callMember("say");

	    JsTypeUtil t = new JsTypeUtil(engine);
	    System.out.println(t.newArray(1,2,3));
	    System.out.println(t.newObject());

	    ScriptObjectMirror dateConstructor = (ScriptObjectMirror) b.get("Date");
	    Object date = dateConstructor.call(dateConstructor);
	    System.out.println(date);

//	    JsDateUtil d = new JsDateUtil(engine);
//	    System.out.println(d.toNativeDate(new Date().getTime()));
	}
}

redpajama_set_name: RedPajamaGithub


text:
import regex

def sentence_case(string):
    """
    Converts a string to sentence case.
    From http://stackoverflow.com/questions/39969202/convert-uppercase-string-to-sentence-case-in-python
    Args:
        string: The input string

    Returns:
        The string, now in sentence case
    """
    return '. '.join(i.capitalize() for i in string.split('. '))

def fix_40char_text(text):
    return sentence_case(regex.sub(r'\s{2,}', " ", text))


text:
package org.apache.cassandra.db.virtual;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Functions;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;

import org.apache.cassandra.audit.AuditLogOptions;
import org.apache.cassandra.config.*;
import org.apache.cassandra.db.DecoratedKey;
import org.apache.cassandra.db.marshal.UTF8Type;
import org.apache.cassandra.dht.LocalPartitioner;
import org.apache.cassandra.schema.TableMetadata;
import org.apache.cassandra.transport.ServerError;

final class SettingsTable extends AbstractVirtualTable
{
    private static final String NAME = "name";
    private static final String VALUE = "value";

    @VisibleForTesting
    static final Map<String, Field> FIELDS =
        Arrays.stream(Config.class.getFields())
              .filter(f -> !Modifier.isStatic(f.getModifiers()))
              .collect(Collectors.toMap(Field::getName, Functions.identity()));

    @VisibleForTesting
    final Map<String, BiConsumer<SimpleDataSet, Field>> overrides =
        ImmutableMap.<String, BiConsumer<SimpleDataSet, Field>>builder()
                    .put("audit_logging_options", this::addAuditLoggingOptions)
                    .put("client_encryption_options", this::addEncryptionOptions)
                    .put("server_encryption_options", this::addEncryptionOptions)
                    .put("transparent_data_encryption_options", this::addTransparentEncryptionOptions)
                    .build();

    private final Config config;

    SettingsTable(String keyspace)
    {
        this(keyspace, DatabaseDescriptor.getRawConfig());
    }

    SettingsTable(String keyspace, Config config)
    {
        super(TableMetadata.builder(keyspace, "settings")
                           .comment("current settings")
                           .kind(TableMetadata.Kind.VIRTUAL)
                           .partitioner(new LocalPartitioner(UTF8Type.instance))
                           .addPartitionKeyColumn(NAME, UTF8Type.instance)
                           .addRegularColumn(VALUE, UTF8Type.instance)
                           .build());
        this.config = config;
    }

    @VisibleForTesting
    Object getValue(Field f)
    {
        Object value;
        try
        {
            value = f.get(config);
        }
        catch (IllegalAccessException | IllegalArgumentException e)
        {
            throw new ServerError(e);
        }
        return value;
    }

    private void addValue(SimpleDataSet result, Field f)
    {
        Object value = getValue(f);
        if (value == null)
        {
            result.row(f.getName());
        }
        else if (overrides.containsKey(f.getName()))
        {
            overrides.get(f.getName()).accept(result, f);
        }
        else
        {
            if (value.getClass().isArray())
                value = Arrays.toString((Object[]) value);
            result.row(f.getName()).column(VALUE, value.toString());
        }
    }

    @Override
    public DataSet data(DecoratedKey partitionKey)
    {
        SimpleDataSet result = new SimpleDataSet(metadata());
        String name = UTF8Type.instance.compose(partitionKey.getKey());
        Field field = FIELDS.get(name);
        if (field != null)
        {
            addValue(result, field);
        }
        else
        {
            // rows created by overrides might be directly queried so include them in result to be possibly filtered
            for (String override : overrides.keySet())
                if (name.startsWith(override))
                    addValue(result, FIELDS.get(override));
        }
        return result;
    }

    @Override
    public DataSet data()
    {
        SimpleDataSet result = new SimpleDataSet(metadata());
        for (Field setting : FIELDS.values())
            addValue(result, setting);
        return result;
    }

    private void addAuditLoggingOptions(SimpleDataSet result, Field f)
    {
        Preconditions.checkArgument(AuditLogOptions.class.isAssignableFrom(f.getType()));

        AuditLogOptions value = (AuditLogOptions) getValue(f);
        result.row(f.getName() + "_enabled").column(VALUE, Boolean.toString(value.enabled));
        result.row(f.getName() + "_logger").column(VALUE, value.logger.class_name);
        result.row(f.getName() + "_audit_logs_dir").column(VALUE, value.audit_logs_dir);
        result.row(f.getName() + "_included_keyspaces").column(VALUE, value.included_keyspaces);
        result.row(f.getName() + "_excluded_keyspaces").column(VALUE, value.excluded_keyspaces);
        result.row(f.getName() + "_included_categories").column(VALUE, value.included_categories);
        result.row(f.getName() + "_excluded_categories").column(VALUE, value.excluded_categories);
        result.row(f.getName() + "_included_users").column(VALUE, value.included_users);
        result.row(f.getName() + "_excluded_users").column(VALUE, value.excluded_users);
    }

    private void addEncryptionOptions(SimpleDataSet result, Field f)
    {
        Preconditions.checkArgument(EncryptionOptions.class.isAssignableFrom(f.getType()));

        EncryptionOptions value = (EncryptionOptions) getValue(f);
        result.row(f.getName() + "_enabled").column(VALUE, Boolean.toString(value.isEnabled()));
        result.row(f.getName() + "_algorithm").column(VALUE, value.algorithm);
        result.row(f.getName() + "_protocol").column(VALUE, value.protocol);
        result.row(f.getName() + "_cipher_suites").column(VALUE, value.cipher_suites.toString());
        result.row(f.getName() + "_client_auth").column(VALUE, Boolean.toString(value.require_client_auth));
        result.row(f.getName() + "_endpoint_verification").column(VALUE, Boolean.toString(value.require_endpoint_verification));
        result.row(f.getName() + "_optional").column(VALUE, Boolean.toString(value.optional));

        if (value instanceof EncryptionOptions.ServerEncryptionOptions)
        {
            EncryptionOptions.ServerEncryptionOptions server = (EncryptionOptions.ServerEncryptionOptions) value;
            result.row(f.getName() + "_internode_encryption").column(VALUE, server.internode_encryption.toString());
            result.row(f.getName() + "_legacy_ssl_storage_port").column(VALUE, Boolean.toString(server.enable_legacy_ssl_storage_port));
        }
    }

    private void addTransparentEncryptionOptions(SimpleDataSet result, Field f)
    {
        Preconditions.checkArgument(TransparentDataEncryptionOptions.class.isAssignableFrom(f.getType()));

        TransparentDataEncryptionOptions value = (TransparentDataEncryptionOptions) getValue(f);
        result.row(f.getName() + "_enabled").column(VALUE, Boolean.toString(value.enabled));
        result.row(f.getName() + "_cipher").column(VALUE, value.cipher);
        result.row(f.getName() + "_chunk_length_kb").column(VALUE, Integer.toString(value.chunk_length_kb));
        result.row(f.getName() + "_iv_length").column(VALUE, Integer.toString(value.iv_length));
    }
}


text:
#!/bin/bash
set -e

LDAP_ALLOW_INSECURE=${LDAP_ALLOW_INSECURE:-false}
SAMBA_REALM=${SAMBA_REALM:-SAMBA.LAN}
# Populate $SAMBA_OPTIONS
SAMBA_OPTIONS=${SAMBA_OPTIONS:-}
HOSTNAME=${HOSTNAME:-"hostname -f"}

[ -n "$SAMBA_DOMAIN" ] \
    && SAMBA_OPTIONS="$SAMBA_OPTIONS --domain=$SAMBA_DOMAIN" \
    || SAMBA_OPTIONS="$SAMBA_OPTIONS --domain=${SAMBA_REALM%%.*}"

[ -n "$SAMBA_HOST_IP" ] && SAMBA_OPTIONS="$SAMBA_OPTIONS --host-ip=$SAMBA_HOST_IP"

SETUP_LOCK_FILE="/var/lib/samba/private/.setup.lock.do.not.remove"

appSetup () {

# If $SAMBA_PASSWORD is not set, generate a password
SAMBA_PASSWORD=${SAMBA_PASSWORD:-`(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c20; echo) 2>/dev/null`}
KERBEROS_PASSWORD=${KERBEROS_PASSWORD:-`(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c20; echo) 2>/dev/null`}
echo "Samba password set to: $SAMBA_PASSWORD"
echo "Kerberos password set to: $KERBEROS_PASSWORD"

# Provision domain
rm -f /etc/samba/smb.conf
rm -rf /var/lib/samba/*
mkdir -p /var/lib/samba/private
samba-tool domain provision \
    --use-rfc2307 \
    --realm=${SAMBA_REALM} \
    --adminpass=${SAMBA_PASSWORD} \
    --server-role=dc \
    --dns-backend=SAMBA_INTERNAL \
    $SAMBA_OPTIONS \
    --option="bind interfaces only"=yes

	#create LDAP INSECURE
    if [ "${LDAP_ALLOW_INSECURE,,}" == "true" ]; then
	     sed -i "/\[global\]/a \\\ldap server require strong auth = no" /etc/samba/smb.conf
    fi
	#update LDAP INSECURE
#    if [ "${LDAP_ALLOW_INSECURE,,}" == "true" ]; then
#	     sed -i "s/ldap server require strong auth = .*/ldap server require strong auth = yes/" /etc/samba/smb.conf
#    fi

    # Create Kerberos database
    rm -f /etc/krb5.conf
    ln -sf /var/lib/samba/private/krb5.conf /etc/krb5.conf
    haveged -w 1024
    /usr/sbin/kdb5_util -P $KERBEROS_PASSWORD -r $SAMBA_REALM create -s

    # Export kerberos keytab for use with sssd
    if [ "${OMIT_EXPORT_KEY_TAB}" != "true" ]; then
        samba-tool domain exportkeytab /etc/krb5.keytab --principal ${HOSTNAME}\$
    fi

# Move smb.conf
mv /etc/samba/smb.conf /var/lib/samba/private/smb.conf
ln -sf /var/lib/samba/private/smb.conf /etc/samba/smb.conf

# add dns-forwarder if required
[ -n "$SAMBA_DNS_FORWARDER" ] \
    && sed -i "/\[global\]/a \\\dns forwarder = $SAMBA_DNS_FORWARDER" /var/lib/samba/private/smb.conf
# Update dns-forwarder if required
#[ -n "$SAMBA_DNS_FORWARDER" ] \
#    && sed -i "s/dns forwarder = .*/dns forwarder = $SAMBA_DNS_FORWARDER/" /var/lib/samba/private/smb.conf

# Mark samba as setup
touch "${SETUP_LOCK_FILE}"

# Setup only?
[ -n "$SAMBA_SETUP_ONLY" ] && exit 127 || :

}

appStart () {
# Fix nameserver
echo -e "search ${SAMBA_REALM}\nnameserver 127.0.0.1" > /etc/resolv.conf
echo -e "127.0.0.1 $HOSTNAME" > /etc/hosts
echo -e "$HOSTNAME" > /etc/hostname
    # setup
    if [ ! -f "${SETUP_LOCK_FILE}" ]; then
      appSetup
    fi
    # ssh
    if [ -f "/runssh.sh" ]; then /runssh.sh; fi
        # Recreate Kerberos database
    if [ ! -f "/var/lib/krb5kdc/principal" ]; then
	rm -f /etc/krb5.conf
	ln -sf /var/lib/samba/private/krb5.conf /etc/krb5.conf
	haveged -w 1024
        /usr/sbin/kdb5_util -P $KERBEROS_PASSWORD -r $SAMBA_REALM create -s
        samba-tool domain exportkeytab /etc/krb5.keytab --principal ${HOSTNAME}\$
    fi

    # run
    /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
}

appHelp () {
	echo "Available options:"
	echo " app:start          - Starts all services needed for Samba AD DC"
	echo " app:setup          - First time setup."
	echo " app:setup_start    - First time setup and start."
	echo " app:help           - Displays the help"
	echo " [command]          - Execute the specified linux command eg. /bin/bash."
}

case "$1" in
	app:start)
		appStart
		;;
	app:setup)
		appSetup
		;;
	app:setup_start)
		appSetup
		appStart
		;;
	app:help)
		appHelp
		;;
	*)
		if [ -x $1 ]; then
			$1
		else
			prog=$(which $1)
			if [ -n "${prog}" ] ; then
				shift 1
				$prog $@
			else
				appHelp
			fi
		fi
		;;
esac

# option with entrypoint
if [ -f "/option.sh" ]; then /option.sh; fi

exit 0


text:
'use strict';

/**
 * Mixin for form capabilities (some sort of data-binding)
 *
 * init:
 *
 * mixins: [
 *    mixinForm({
 *      // required
 *      viewModelName: 'ModelName', // name of model
 *      // optional
 *      name: 'formName', // form name (default "form")
 *      dataPropertyName: 'data', // initial data (object or name of corresponding property name (this.props['name']) (default "data")
 *      labelErrorClassName: '', // if empty, uses "{name}-label-error"
 *      labelSuccessClassName: '', // if empty, uses "{name}-label-success"
 *      inputErrorClassName: '', // if empty, uses "{name}-input-error"
 *      inputSuccessClassName: '' // if empty, uses "{name}-input-success"
 *    }, models) // {ModelName: Backbone.Model() }
 * ]
 *
 * using:
 *
 * <label className={this.formName().labelClassName('name')}>Title Name:</label>
 *
 * <Input type="text"
 *      value={this.formName().value('name')}
 *      onChange={this.formName().onChange('name')}
 *      className={this.formName().classNameInput('name')} />
 *
 * <ImageUploader
 *     value={this.formName().value('icons[name=ipad152x152].uri')}
 *     onChange={this.formName().onChange('icons[name=ipad152x152].uri')} />
 *
 * or simple syntax
 *
 * <Input type="text" {...this.formName().attribute('name)} />
 *
 * <ImageUploader {...this.formName().attribute('icons[name=ipad152x152].uri')} />
 *
 * labelClassName('attribute name') - returns css class name for validated label
 * inputClassName('attribute name') - returns css class name for validated input
 * model - return model
 * value('attribute name') - returns value
 * onChange('attribute name') - returns onChange callback
 * errors() - returns list of errors for whole model
 * isValid() - checks model is valid
 * validate() - runs model validation
 * attribute('attribute name') - uses spread attributes
 *
 */

var _ = require('lodash');

/**
 * 'icons[name=ipad152x152].uri'
 * to
 * ['icons', {'name': 'ipad152x152'}, 'uri'}
 */

var cachedNestedAttributes = {};

var getNestedAttribute = function (attribute) {

    if (!cachedNestedAttributes[attribute]) {
        var list = [];
        var chains = attribute.split('.');

        _.each(chains, function (chain) {

            if (chain.indexOf('[') !== -1) {
                // collection
                var subKeys = chain.split('[');

                var conditions = {};
                _.each(subKeys.slice(1), function (subKey) {
                    subKey = subKey.substr(0, subKey.length - 1);
                    var pos = subKey.indexOf('=');
                    if (pos > 0) {
                        conditions[subKey.substr(0, pos)] = subKey.substring(pos + 1);
                    }
                });
                list.push(subKeys[0]);
                list.push(conditions);

            } else {
                // object
                list.push(chain);
            }

        });
        cachedNestedAttributes[attribute] = list;
    }
    return JSON.parse(JSON.stringify(cachedNestedAttributes[attribute]));
};

/**
 *
 */

var getPath = function (list) {
    return _.reduce(list, function (result, attr) {
        return result + (_.isNumber(attr) ? ('[' + attr + ']') : ('.' + attr));
    });
};

var getParamsByAttribute = function (modelData, attribute, value) {

    var data = modelData;
    var listOfAttributes = [];
    var existedAttribute = '';

    _.each(getNestedAttribute(attribute), function (chain, index, list) {
        if (_.isString(chain)) {
            if (_.isUndefined(data[chain])) {
                data[chain] = _.isUndefined(list[index + 1]) ? value : (_.isString(list[index + 1]) ? {} : []);
                existedAttribute = existedAttribute || _.clone(listOfAttributes);
            }
            data = data[chain];
            listOfAttributes.push(chain);
        } else {
            if (_.isArray(data)) {
                var number;
                for (var i = 0; i < data.length; i++) {
                    if (_.find([data[i]], chain)) {
                        data = data[i];
                        number = i;
                        break;
                    }
                }
                if (_.isUndefined(number)) {
                    data.push(chain);
                    number = data.length - 1;
                    data = data[number];
                    existedAttribute = existedAttribute || _.clone(listOfAttributes);
                }
                listOfAttributes.push(number);
            }
        }
    });
    existedAttribute = existedAttribute || _.clone(listOfAttributes);

    var normalizedAttribute = getPath(listOfAttributes);
    var normalizedExistedAttribute = getPath(existedAttribute);
    if (_.isUndefined(normalizedExistedAttribute)) {
        normalizedExistedAttribute = normalizedAttribute;
    }

    var dataForInsert;
    if (normalizedExistedAttribute === normalizedAttribute) {
        dataForInsert = value;
    } else {
        dataForInsert = modelData;
        _.each(existedAttribute, function (attr) {
            if (!_.isUndefined(dataForInsert[attr])) {
                dataForInsert = dataForInsert[attr];
            }
        });
    }

    return [data, normalizedAttribute, normalizedExistedAttribute, dataForInsert];
};

module.exports = function factoryFormMixin(params, models) {

    var name = params.name || 'form';
    var viewModelName = params['viewModelName'];
    var dataPropertyName = params['dataPropertyName'] || 'data';

    if (!viewModelName || !models[viewModelName]) {
        return {};
    }

    var viewModelProp = 'viewModel' + name;

    var handleValidated = function (isValid, model, errors) {
        var state = {};
        state[name + '-errors'] = errors;
        _.each(_.keys(model.attributes), function (attribute) {
            state[name + '-error-' + attribute] = errors[attribute];
        });
        this.setState(state);
    };

    var setInitData = function (initData, props) {
        props = props || this.props;
        if (_.isString(initData)) {
            if (props[initData]) {
                this[viewModelProp].set(props[initData]);
            }
        } else {
            this[viewModelProp].set(initData);
        }
    };

    var mixin = {

        componentWillMount: function () {
            this[viewModelProp] = new models[viewModelName]();
            setInitData.call(this, dataPropertyName);
            this[viewModelProp].on('validated', handleValidated, this);
        },

        componentWillUpdate: function (nextProps) {
            if (_.isString(dataPropertyName) && nextProps[dataPropertyName] && !_.isEqual(nextProps[dataPropertyName], this.props[dataPropertyName])) {
                setInitData.call(this, dataPropertyName, nextProps);
            }
        },

        componentWillUnmount: function () {
            this[viewModelProp].off('validated', handleValidated, this);
        }

    };

    mixin[name] = function () {

        var that = this;

        var funcValue = function (attribute) {
            return getParamsByAttribute(that[viewModelProp].toJSON(), attribute)[0];
        };

        var funcValidate = function (attrs) {
            var errors = that[viewModelProp].preValidate(attrs);
            var state = {};
            var stateErrors = _.cloneDeep(_.isPlainObject(that.state) && that.state[name + '-errors']) || {};
            _.each(_.keys(attrs), function (attribute) {
                var error = errors && errors[attribute];
                state[name + '-error-' + attribute] = error;
                stateErrors[attribute] = error ? error : undefined;
            });
            state[name + '-errors'] = stateErrors;
            !_.isEmpty(state) && that.setState(state);
        };

        var funcOnChange = function (attribute) {
            var isComplexAttribute = attribute.indexOf('.') !== -1 || attribute.indexOf('[') !== 1;
            return function (event) {
                event.stopPropagation && event.stopPropagation();
                var value = event.target ? event.target.value : event;

                var params = getParamsByAttribute(this[viewModelProp].toJSON(), attribute, value);

                var data = {};
                // if we want update a whole object
                if (params[2].substr(-1) === ']') {
                    _.each(params[3], function (value, key) {
                        data[params[2] + '.' + key] = value;
                    });
                } else {
                    // if we want update just one field in an object
                    data[params[2]] = params[3];
                }

                this[viewModelProp].set(data, {forceUpdate: true});
                if (isComplexAttribute) {
                    this[viewModelProp].trigger('change', this[viewModelProp]);
                }

                _.defer(function () {
                    funcValidate(data);
                });

            }.bind(that);
        };

        var funcClassNameLabel = function (attribute, emptyByDefault) {
            var stateName = name + '-error-' + attribute;
            var className = (_.isNull(that.state) || _.isUndefined(that.state[name + '-errors'])) && emptyByDefault ?
                '' :
                (that.state && that.state[stateName] ?
                params['labelErrorClassName'] || (name + '-label-error') :
                params['labelSuccessClassName'] || (name + '-label-success'));
            return className ? (_.isFunction(that.className) ? that.className(className) : className) : '';
        };

        var funcClassNameInput = function (attribute, emptyByDefault) {
            var stateName = name + '-error-' + attribute;
            var className = (_.isNull(that.state) || _.isUndefined(that.state[name + '-errors'])) && emptyByDefault ?
                '' :
                (that.state && that.state[stateName] ?
                params['inputErrorClassName'] || (name + '-input-error') :
                params['inputSuccessClassName'] || (name + '-input-success'));
            return className ? (_.isFunction(that.className) ? that.className(className) : className) : '';
        };

        return {

            value: funcValue,
            onChange: funcOnChange,
            labelClassName: funcClassNameLabel,
            inputClassName: funcClassNameInput,
            model: that[viewModelProp],
            validate: funcValidate,

            errors: function (attribute) {
                var errors = that.state[name + '-errors'] || {};
                return attribute ? errors[attribute] : errors;
            },

            isValid: function () {
                return _.isEmpty(that[viewModelProp].preValidate(that[viewModelProp].attributes));
            },

            toJSON: function () {
                return that[viewModelProp].toJSON();
            },

            attribute: function (attribute) {
                return {
                    value: funcValue(attribute),
                    onChange: funcOnChange(attribute),
                    className: funcClassNameInput(attribute, true)
                };
            }

        };

    };

    return mixin;

};


text:
package e2e

import (
	"flag"
	"fmt"
	"path/filepath"
	"strings"
	"testing"
	"time"

	cs "github.com/appscode/searchlight/client/clientset/versioned"
	"github.com/appscode/searchlight/pkg/icinga"
	"github.com/appscode/searchlight/pkg/operator"
	"github.com/appscode/searchlight/test/e2e/framework"
	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/reporters"
	. "github.com/onsi/gomega"
	core "k8s.io/api/core/v1"
	crd_cs "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
	"kmodules.xyz/client-go/logs"
)

var (
	provider           string
	storageClass       string
	searchlightService string
)

func init() {
	flag.StringVar(&provider, "provider", "minikube", "Kubernetes cloud provider")
	flag.StringVar(&storageClass, "storageclass", "", "Kubernetes StorageClass name")
	flag.StringVar(&searchlightService, "searchlight-service", "", "Running searchlight reference")
}

const (
	TIMEOUT = 20 * time.Minute
)

var (
	op   *operator.Operator
	root *framework.Framework
)

func TestE2e(t *testing.T) {
	logs.InitLogs()
	RegisterFailHandler(Fail)
	SetDefaultEventuallyTimeout(TIMEOUT)

	junitReporter := reporters.NewJUnitReporter("junit.xml")
	RunSpecsWithDefaultAndCustomReporters(t, "e2e Suite", []Reporter{junitReporter})
}

var _ = BeforeSuite(func() {

	Expect(searchlightService).ShouldNot(BeEmpty())

	// Kubernetes config
	kubeconfigPath := filepath.Join(homedir.HomeDir(), ".kube/config")
	By("Using kubeconfig from " + kubeconfigPath)
	config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath)
	Expect(err).NotTo(HaveOccurred())
	// Clients
	Expect(err).NotTo(HaveOccurred())
	kubeClient := kubernetes.NewForConfigOrDie(config)
	apiExtKubeClient := crd_cs.NewForConfigOrDie(config)
	extClient := cs.NewForConfigOrDie(config)
	// Framework
	root = framework.New(kubeClient, apiExtKubeClient, extClient, nil, provider, storageClass)

	framework.PrintSeparately("Using namespace " + root.Namespace())

	// Create namespace
	err = root.CreateNamespace()
	Expect(err).NotTo(HaveOccurred())

	parts := strings.Split(searchlightService, "@")
	Expect(len(parts)).Should(BeIdenticalTo(2))
	om := metav1.ObjectMeta{
		Name:      parts[0],
		Namespace: parts[1],
	}
	slService := &core.Service{ObjectMeta: om}

	// Get Icinga Ingress Hostname
	endpoint, err := root.GetServiceEndpoint(slService.ObjectMeta, "icinga")
	Expect(err).NotTo(HaveOccurred())

	// Icinga Config
	cfg := &icinga.Config{
		Endpoint: fmt.Sprintf("https://%v/v1", endpoint),
		CACert:   nil,
	}

	cfg.BasicAuth.Username = ICINGA_API_USER
	cfg.BasicAuth.Password, err = root.Invoke().GetIcingaApiPassword(om)
	Expect(err).NotTo(HaveOccurred())

	// Icinga Client
	icingaClient := icinga.NewClient(*cfg)
	root = root.SetIcingaClient(icingaClient)
	root.EventuallyIcingaAPI().Should(Succeed())

	icingawebEndpoint, err := root.GetServiceEndpoint(slService.ObjectMeta, "ui")
	Expect(err).NotTo(HaveOccurred())
	fmt.Println()
	fmt.Println("Icingaweb2:     ", fmt.Sprintf("http://%v/", icingawebEndpoint))
	fmt.Println("Login password: ", ICINGA_WEB_UI_PASSWORD)
	fmt.Println()

})

var _ = AfterSuite(func() {
	root.CleanPodAlert()
	root.CleanNodeAlert()
	root.CleanClusterAlert()
	err := root.DeleteNamespace()
	Expect(err).NotTo(HaveOccurred())
	framework.PrintSeparately("Deleted namespace")
})


text:
namespace rj_geometry {

Polygon::Polygon(const Rect& rect) {
    vertices.resize(4);
    vertices[0] = rect.pt[0];
    vertices[1] = Point(rect.pt[1].x(), rect.pt[0].y());
    vertices[2] = rect.pt[1];
    vertices[3] = Point(rect.pt[0].x(), rect.pt[1].y());
}

Polygon::Polygon(std::vector<Point> verts) { vertices = std::move(verts); }

Shape* Polygon::clone() const { return new Polygon(*this); }

void Polygon::init(const Segment& seg, float r, float length) {
    Point dir;
    if (length != 0.0f) {
        dir = seg.delta() / length;
    } else {
        // Degenerate segment, so direction doesn't matter as long as it's a
        // unit vector.
        dir = Point(1, 0);
    }

    Point v = dir * r;
    Point u = v.perp_ccw();

    vertices.resize(4);
    vertices[0] = seg.pt[0] - u - v;
    vertices[1] = seg.pt[0] + u - v;
    vertices[2] = seg.pt[1] + u + v;
    vertices[3] = seg.pt[1] - u + v;
}

Rect Polygon::bbox() const {
    Rect rect(vertices[0]);

    for (unsigned int i = 1; i < vertices.size(); ++i) {
        rect.expand(vertices[i]);
    }

    return rect;
}

bool Polygon::intersects(const Rect& rect) const { return intersects(Polygon(rect)); }

bool Polygon::intersects(const Polygon& other) const {
    return contains_vertex(other) || other.contains_vertex(*this);
}

bool Polygon::contains_vertex(const Polygon& other) const {
    for (auto vertice : other.vertices) {
        if (contains_point(vertice)) {
            return true;
        }
    }

    return false;
}

bool Polygon::near_point(Point pt, float threshold) const {
    if (contains_point(pt)) {
        return true;
    }

    unsigned int i = vertices.size() - 1;
    for (unsigned int j = 0; j < vertices.size(); ++j) {
        Segment edge(vertices[i], vertices[j]);
        if (edge.near_point(pt, threshold)) {
            return true;
        }

        i = j;
    }

    return false;
}

bool Polygon::near_segment(const Segment& seg, float threshold) const {
    if (contains_point(seg.pt[0]) || contains_point(seg.pt[1])) {
        return true;
    }

    unsigned int i = vertices.size() - 1;
    for (unsigned int j = 0; j < vertices.size(); ++j) {
        Segment edge(vertices[i], vertices[j]);
        if (edge.near_segment(seg, threshold)) {
            return true;
        }

        i = j;
    }

    return false;
}

bool Polygon::contains_point(Point pt) const {
    // FIXME (Ben) - Replace this with the optimized wrap-number test.

    // http://www.geometryalgorithms.com/Archive/algorithm_0103/algorithm_0103.h
    // tm isLeft in their description does not actually indicate if a point is
    // on the -X side of a line.  It is the same as my Line::point_side.
    //
    // Simple explanation:
    // Consider a ray along +X starting at this point. Go around the polygon and
    // look at every intersection of an edge with this ray. Since you are
    // following the polygon's edges in order, if this point is outside the
    // polygon the ray will intersect the same number of up-going and down-going
    // edges.
    //
    // Consider the case of a convex polygon with this point outside: The ray
    // will intersect exactly one up-going edge and one down-going edge. For a
    // non-convex polygon, the ray will intersect zero or more additional pairs
    // of up-going and down-going edges.
    //
    // Increment count for each up-going edge and decrement for each down-going
    // edge. count==0 iff the point is outside.
    //
    // This handles cases where the ray intersects vertices too. Only the
    // endpoint with the smallest Y-value is considered. If the ray is outside
    // the polygon, then both edges will be counted because one will be up-going
    // and one down-going at the vertex. If the ray is inside the polygon, both
    // edges are going in the same direction so the vertex will only be checked
    // for one of them.

    int count = 0;
    unsigned int i = vertices.size() - 1;
    for (unsigned int j = 0; j < vertices.size(); j++) {
        const Point& p1 = vertices[i];
        const Point& p2 = vertices[j];
        i = j;

        if (p1.y() <= pt.y()) {
            if (p2.y() > pt.y()) {
                // Edge is going up
                if (Line(p1, p2).point_side(pt) > 0) {
                    ++count;
                }
            }
        } else {
            if (p2.y() <= pt.y()) {
                // Edge is going down
                if (Line(p1, p2).point_side(pt) < 0) {
                    --count;
                }
            }
        }
    }

    return count != 0;
}

bool Polygon::hit(Point pt) const { return near_point(pt, kRobotRadius); }

bool Polygon::hit(const Segment& seg) const { return near_segment(seg, kRobotRadius); }

}  // namespace rj_geometry


text:
package brooklyn.location.docker.strategy;

import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Functions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.reflect.TypeToken;

import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.flags.SetFromFlag;

import brooklyn.location.docker.DockerHostLocation;

/**
 * Placement strategy that checks labels on hosts.
 */
public class LabelPlacementStrategy extends BasicDockerPlacementStrategy {

    private static final Logger LOG = LoggerFactory.getLogger(LabelPlacementStrategy.class);

    @SetFromFlag("labels")
    public static final ConfigKey<List<String>> LABELS = ConfigKeys.newConfigKey(
            new TypeToken<List<String>>() { },
            "docker.constraint.labels",
            "The list of required labels", ImmutableList.<String>of());

    @Override
    public boolean apply(DockerHostLocation input) {
        Set<String> labels = MutableSet.copyOf(config().get(LABELS));
        if (labels.isEmpty()) return true;
        Set<String> tags = MutableSet.copyOf(Iterables.transform(input.getMachine().tags().getTags(), Functions.toStringFunction()));
        labels.removeAll(tags);
        LOG.debug("Host {} : Tags {} : Remaining {}",
                new Object[] { input, Iterables.toString(tags), labels.isEmpty() ? "none" : Iterables.toString(labels) });

        return labels.isEmpty();
    }
}


text:
package org.fjorum.controller.form;

import org.fjorum.model.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

@Component
public class CategoryCreateValidator implements Validator {

    private final CategoryService categoryService;

    @Autowired
    public CategoryCreateValidator(CategoryService categoryService) {
        this.categoryService = categoryService;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return CategoryCreateForm.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        CategoryCreateForm form = (CategoryCreateForm) target;
        categoryService.getById(form.getParentId()).<Runnable>map(parent -> () -> {
                    if (parent.getChildren().stream().anyMatch(c -> c.getName().equals(form.getName()))) {
                        errors.reject("category.nameExists", "There is already a category with the same name");
                    }
                }
        ).orElse(() -> errors.reject("category.noParentFound", "Could not find parent category")
        ).run();
    }
}


text:
package org.springframework.cloud.netflix.ribbon;

import java.util.Map;

import com.netflix.loadbalancer.Server;

/**
 * @author Spencer Gibb
 */
public interface ServerIntrospector {

	boolean isSecure(Server server);

	Map<String, String> getMetadata(Server server);
}


text:
<?php

namespace SensioLabs\Melody\Script;

use SensioLabs\Melody\Configuration\ScriptConfiguration;
use SensioLabs\Melody\Resource\Resource;

/**
 * Script.
 *
 * @author Grégoire Pineau <lyrixx@lyrixx.info>
 */
class Script
{
    private $resource;
    private $arguments;
    private $configuration;

    public function __construct(Resource $resource, array $arguments, ScriptConfiguration $configuration)
    {
        $this->resource = $resource;
        $this->arguments = $arguments;
        $this->configuration = $configuration;
    }

    public function getResource()
    {
        return $this->resource;
    }

    public function getArguments()
    {
        return $this->arguments;
    }

    public function getConfiguration()
    {
        return $this->configuration;
    }

    public function getPackages()
    {
        return $this->configuration->getPackages();
    }

    public function getRepositories()
    {
        return $this->configuration->getRepositories();
    }
}


text:
using Microsoft.AspNetCore.Http;

namespace Microsoft.AspNetCore.Antiforgery;

/// <summary>
/// Provides access to the antiforgery system, which provides protection against
/// Cross-site Request Forgery (XSRF, also called CSRF) attacks.
/// </summary>
public interface IAntiforgery
{
    /// <summary>
    /// Generates an <see cref="AntiforgeryTokenSet"/> for this request and stores the cookie token
    /// in the response. This operation also sets the "Cache-control" and "Pragma" headers to "no-cache" and
    /// the "X-Frame-Options" header to "SAMEORIGIN".
    /// </summary>
    /// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param>
    /// <returns>An <see cref="AntiforgeryTokenSet" /> with tokens for the response.</returns>
    /// <remarks>
    /// This method has a side effect:
    /// A response cookie is set if there is no valid cookie associated with the request.
    /// </remarks>
    AntiforgeryTokenSet GetAndStoreTokens(HttpContext httpContext);

    /// <summary>
    /// Generates an <see cref="AntiforgeryTokenSet"/> for this request.
    /// </summary>
    /// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param>
    /// <returns>The <see cref="AntiforgeryTokenSet"/> for this request.</returns>
    /// <remarks>
    /// Unlike <see cref="GetAndStoreTokens(HttpContext)"/>, this method has no side effect. The caller
    /// is responsible for setting the response cookie and injecting the returned
    /// form token as appropriate.
    /// </remarks>
    AntiforgeryTokenSet GetTokens(HttpContext httpContext);

    /// <summary>
    /// Asynchronously returns a value indicating whether the request passes antiforgery validation. If the
    /// request uses a safe HTTP method (GET, HEAD, OPTIONS, TRACE), the antiforgery token is not validated.
    /// </summary>
    /// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param>
    /// <returns>
    /// A <see cref="Task{Boolean}"/> that, when completed, returns <c>true</c> if the request uses a safe HTTP
    /// method or contains a valid antiforgery token, otherwise returns <c>false</c>.
    /// </returns>
    Task<bool> IsRequestValidAsync(HttpContext httpContext);

    /// <summary>
    /// Validates an antiforgery token that was supplied as part of the request.
    /// </summary>
    /// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param>
    /// <returns>A <see cref="Task"/> that completes when validation has completed.</returns>
    /// <exception cref="AntiforgeryValidationException">
    /// Thrown when the request does not include a valid antiforgery token.
    /// </exception>
    Task ValidateRequestAsync(HttpContext httpContext);

    /// <summary>
    /// Generates and stores an antiforgery cookie token if one is not available or not valid.
    /// </summary>
    /// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param>
    void SetCookieTokenAndHeader(HttpContext httpContext);
}


text:
<?php
/**
 * Created by PhpStorm.
 * User: Dmitriy Pivovarov aka AngryDeer http://studioweb.pro
 * Date: 25.01.16
 * Time: 4:55
 */?>
@extends('layouts.master')
@section('content')
    {!! Form::open(['class'=>'small-form']) !!}
    @include('widgets.form._formitem_password', ['name' => 'password', 'title' => trans('auth.password'), 'placeholder' => trans('auth.password') ])
    @include('widgets.form._formitem_password', ['name' => 'password_confirm', 'title' => trans('auth.password_confirm'), 'placeholder' => trans('auth.password') ])
    @include('widgets.form._formitem_btn_submit', ['title' => trans('auth.confirm')])
    {!! Form::close() !!}
@stop


text:
function Parameters = updategraph(Parameters, ~)
%UNTITLED Summary of this function goes here
%   Detailed explanation goes here

arrayfun(@(x) refreshdata(x.Handle), Parameters.Graph.Figure);
drawnow expose;

end

%
%     function updatefigure(FigureStruct)
%         arrayfun(@updateaxis, FigureStruct.Axis);
%     end
%
%     function updateaxis(AxisStruct)
%         arrayfun(@updateLine, AxisStruct.Line);
%     end
%
%     function updateLine(LineStruct)
%         iTime = Parameters.Simulation.iTime; %#ok<NASGU>
%         eval(['yData = squeeze(' LineStruct.sourceDataY ');']);
%         eval(['xData = squeeze(' LineStruct.sourceDataX ');']);
%
%         set(LineStruct.Handle, 'YData', yData);
%         set(LineStruct.Handle, 'XData', xData);
%     end
% arrayfun(@updatefigure, Parameters.Graph.Figure);