class textu
{
public:
	long COMval;
	char *tName;
	char flag;	// 0 normal, 1 alpha texture
	long sizex,sizey;
	long decal, masqX, masqY;	// for soft optimisation
	void *data;

		// methods:
	textu();
	void initPtr();
	bool loadIMG(bool);
	bool loadIMG(bool, char *);
	~textu();
};


//	-------------------------- textures methods -------------------------------

textu::textu()
{
	tName = NULL;
	data = NULL;
	COMval = 1;
	flag = 0;
}

void textu::initPtr()
{
}
#ifndef PLATFORM_LINUX
long GetIMGType(char *file)
{
	char *pfile = file + strlen(file);
	while (pfile[0] != '.') pfile--;
	strlwr(pfile);

	if (!strcmp(pfile, ".tga"))
		return 0;
	else if (!strcmp(pfile, ".jpg"))
		return 1;
	else if (!strcmp(pfile, ".bmp"))
		return 2;
	else
		return -1;
}
#endif
bool checkSize(long number)
{
	long foundbits = 0;
	ULONG masq = 1;
	for(long t=0;t<32;t++)
	{
		if( (masq & number) !=0 ) foundbits++;
		masq<<=1;
	}
	if( foundbits > 1 ) return true;	// bad case
	else return false; // good case
}

bool textu::loadIMG(bool sprite, char *name)
{
	tName = name;
	return loadIMG(sprite);
	tName = NULL;
}

bool textu::loadIMG(bool sprite)
{
#ifdef PLATFORM_LINUX
	bool oktoadd;
	fileOperations iFile(tName,oktoadd);
	if( !oktoadd ) return true;	// unable to load the file

	struct retImage imgData = readJPG(iFile.qloadfile(), iFile.getfilesize());

	sizex = (long)imgData.width;
	sizey = (long)imgData.height;
	data  = imgData.buffer;

	// get decal bits for width
	long cbit = 0;
	unsigned long w = sizex;
	while (!(w & 1))
	{
		cbit++;
		w /= 2;
	}
	decal = cbit;
	masqX = sizex - 1;
	masqY = sizey - 1;

	char alphaName[256];
	long a=0;
	while(tName[a] !=0)a++;
	while(tName[a] != '.')a--;
	long b;
	for(b=0;b<a;b++) alphaName[b] = tName[b];
	alphaName[b++] = '_';
	alphaName[b++] = 'A';
	alphaName[b++] = 'L';
	alphaName[b++] = 'P';
	alphaName[b++] = 'H';
	alphaName[b++] = 'A';
	while(tName[a] !=0) alphaName[b++] = tName[a++];
	alphaName[b++] = 0;

	bool valid;
	fileOperations alphaFile(alphaName, valid);

	// alpha file found
	if( valid )
	{
		imgData = readJPG(alphaFile.qloadfile(), alphaFile.getfilesize());
		// alpha flag
		flag = 1;


		long TGAc, TGAc2;
		uchar *wbuff = (uchar *)imgData.buffer;
		uchar *wbuffFinal = (uchar*)data;
		// copy alpha datas
		for (TGAc2 = 0; TGAc2 < sizey; TGAc2++)
		{
			for (TGAc = 0; TGAc < sizex; TGAc++)
			{
//				B = wbuff[0];
//				G = wbuff[1];
//				R = wbuff[2];
				// use only red for alpha
				wbuffFinal[3] = wbuff[2];
				wbuff += 4;
				wbuffFinal += 4;
			}
		}
//		delete alpha image from memory
		delete imgData.buffer;	// delete alpha image
	}

#else	
	bool oktoadd;
	fileOperations iFile(tName,oktoadd);
	if( !oktoadd ) return true;	// unable to load the file
	IMG	lIMG;
	TARGA lTGA(&lIMG);
	JPEG lJPG(&lIMG);
	BMP	lBMP(&lIMG);
	
	uchar *buff = (unsigned char *)iFile.qloadfile();
	ulong sbuff = iFile.getfilesize();

	lIMG.SetSource(buff, sbuff);
	long type = GetIMGType(tName);

	// decode the buffer
	switch (type)
	{
		case 0:
			lTGA.DecodeBuffer();
			break;
		case 1:
			lJPG.DecodeBuffer();
			break;
		case 2:
			lBMP.DecodeBuffer();
			break;
	}
 
//	reject non exp2 resolution images
	if( !sprite )
	{
		if( checkSize(lIMG.width) ) return true;
		if( checkSize(lIMG.height) ) return true;
	}
	lIMG.Flip(false);
/*	
	// resize if too wide
	if (lIMG.width > 512)
		lIMG.Stretch(512, lIMG.height, 512);
	if (lIMG.height > 512)
		lIMG.Stretch(lIMG.width, 512, lIMG.pitch);
*/

	
	sizex = (long)lIMG.width;
	sizey = (long)lIMG.height;

	// get decal bits for width
	long cbit = 0;
	unsigned long w = lIMG.width;
	while (!(w & 1))
	{
		cbit++;
		w /= 2;
	}
	decal = cbit;
	masqX = lIMG.width - 1;
	masqY = lIMG.height - 1;
		
	data = new USHORT[sizex*sizey];

	uchar *wbuff = (uchar *)lIMG.adress;

	lIMG.UseAfterDeath(true);
	lIMG.GetBGR();
	delete data;
	data = (USHORT*)wbuff;
	// everything went OK!

	char alphaName[256];
	long a=0;
	while(tName[a] !=0)a++;
	while(tName[a] != '.')a--;
	long b;
	for(b=0;b<a;b++) alphaName[b] = tName[b];
	alphaName[b++] = '_';
	alphaName[b++] = 'A';
	alphaName[b++] = 'L';
	alphaName[b++] = 'P';
	alphaName[b++] = 'H';
	alphaName[b++] = 'A';
	while(tName[a] !=0) alphaName[b++] = tName[a++];
	alphaName[b++] = 0;

	bool valid;
	fileOperations alphaFile(alphaName, valid);

	// alpha file found
	if( valid )
	{
		// alpha flag
		flag = 1;

		IMG	lIMG2;
		TARGA lTGA2(&lIMG2);
		JPEG lJPG2(&lIMG2);
		BMP	lBMP2(&lIMG2);
	
		buff = (unsigned char *)alphaFile.qloadfile();
		sbuff = alphaFile.getfilesize();

		lIMG2.SetSource(buff, sbuff);
		type = GetIMGType(alphaFile.name);

		// decode the buffer
		switch (type)
		{
			case 0:
				lTGA2.DecodeBuffer();
				break;
			case 1:
				lJPG2.DecodeBuffer();
				break;
			case 2:
				lBMP2.DecodeBuffer();
				break;
		}
 
//	reject non exp2 resolution images
		if( checkSize(lIMG2.width) ) return true;
		if( checkSize(lIMG2.height) ) return true;
		lIMG2.Flip(false);

		long TGAc, TGAc2;
		wbuff = (uchar *)lIMG2.adress;
		uchar *wbuffFinal = (uchar*)data;
		// copy alpha datas
		for (TGAc2 = 0; TGAc2 < sizey; TGAc2++)
		{
			for (TGAc = 0; TGAc < sizex; TGAc++)
			{
//				B = wbuff[0];
//				G = wbuff[1];
//				R = wbuff[2];
				// use only red for alpha
				wbuffFinal[3] = wbuff[2];
				wbuff += 4;
				wbuffFinal += 4;
			}
		}
//		delete alpha image from memory
		lIMG2.UseAfterDeath(false);
		lIMG2.GetBGR();
	}
#endif
	return false;
}

textu::~textu()
{
	COMval--;
	if( !COMval )
	{
		if( data != NULL )
		{
			delete data;
			data = NULL;
		}
	}

	if(tName != NULL)
	{
		delete tName ;
		tName = NULL;
	}
}
