// ImageCache.cpp: implementation of the CImageCache class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "imagegrinder.h"
#include "ImageCache.h"


 
ImageChain::ImageChain() 
{
HFImg=NULL;
PrvImg=NULL;
TNImg=NULL;
}

ImageChain::~ImageChain()
{
if(HFImg) delete HFImg;
if(PrvImg) delete PrvImg;
if(TNImg) delete TNImg;
}

void ImageChain::BuildHFImg(int nx,int ny)
{
if(HFImg) delete HFImg;
	HFImg=new Image;

Image tmpimg;
tmpimg=OrgImg;

tmpimg.MakeGrayscalePalette();
tmpimg.MakeRGB24();


HFImg->CreateBlank(nx,ny,ITYPE_RGB,24);
HFImg->Blt(tmpimg,
			CRect(0,0,HFImg->GetWidth(),HFImg->GetHeight()),
			CRect(0,0,tmpimg.GetWidth(),tmpimg.GetHeight())
			);

HFImg->MaskTo(RGBMask(0x0000ff,0x00ff00,0xff0000));


}

void ImageChain::BuildPrvImg(int nx,int ny)
{
if(PrvImg) delete PrvImg;
PrvImg=new Image;

Image tmpimg;
tmpimg=OrgImg;

tmpimg.MakeGrayscalePalette();
tmpimg.MakeRGB24();

PrvImg->CreateBlank(nx,ny,ITYPE_RGB,24);
PrvImg->Blt(tmpimg,
			CRect(0,0,PrvImg->GetWidth(),PrvImg->GetHeight()),
			CRect(0,0,tmpimg.GetWidth(),tmpimg.GetHeight())
			);

PrvImg->MaskTo(RGBMask(0xff0000,0x00ff00,0x0000ff));

}

void ImageChain::BuildTNImg(int nx,int ny)
{
if(TNImg) delete TNImg;
TNImg=new Image;

Image tmpimg;
tmpimg=OrgImg;

tmpimg.MakeGrayscalePalette();
tmpimg.MakeRGB24();

TNImg->CreateBlank(nx,ny,ITYPE_RGB,24);
TNImg->Blt(tmpimg,
			CRect(0,0,TNImg->GetWidth(),TNImg->GetHeight()),
			CRect(0,0,tmpimg.GetWidth(),tmpimg.GetHeight())
			);

TNImg->MaskTo(RGBMask(0xff0000,0x00ff00,0x0000ff));
}

Image *ImageChain::GetImage()
{
return &OrgImg;
}

Image *ImageChain::GetHFImage()
{
if(!HFImg) return NULL;
	return HFImg;
}

Image *ImageChain::GetPrvImage()
{
if(!PrvImg) return NULL;
return PrvImg;
}

Image *ImageChain::GetTNImage()
{
if(!TNImg) return NULL;
return TNImg;
}

void ImageChain::LoadImg(CString str)
{
OrgImg.Load((char *)(LPCSTR)str);
}

void ImageChain::SaveChain(FILE *fl)
{
char tag[7]="IMGCHN";
char ver[4]="1.0";
char flag;
fwrite(tag,6,1,fl);
fwrite(ver,3,1,fl);

OrgImg.SaveTga(fl);

if(HFImg)
{
	flag=1; fwrite(&flag,1,1,fl);
	HFImg->SaveTga(fl);
}
else
{ flag=0; fwrite(&flag,1,1,fl); }


if(PrvImg)
{
	flag=1; fwrite(&flag,1,1,fl);
	PrvImg->SaveTga(fl);
}
else
{ flag=0; fwrite(&flag,1,1,fl); }

if(TNImg)
{
	flag=1; fwrite(&flag,1,1,fl);
	TNImg->SaveTga(fl);
}
else
{ flag=0; fwrite(&flag,1,1,fl); }


}

void ImageChain::LoadChain(FILE *fl)
{
char tag[7];
char ver[4];
char flag;
fread(tag,6,1,fl);
fread(ver,3,1,fl);

OrgImg.LoadTga(fl);
Image *img;

fread(&flag,1,1,fl);
if(flag)
{
img=new Image;
img->LoadTga(fl);
HFImg=img;
}

fread(&flag,1,1,fl);
if(flag)
{
img=new Image;
img->LoadTga(fl);
PrvImg=img;
}

fread(&flag,1,1,fl);
if(flag)
{
img=new Image;
img->LoadTga(fl);
TNImg=img;
}


}



//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CImageCache *CImageCache::Instance=NULL;

CImageCache::CImageCache()
{
ImgTot=0;
}

CImageCache::~CImageCache()
{
Clear();
}

void CImageCache::Clear()
{
for(int i=0;i<ImgTot;i++) delete ISet[i];
ImgTot=0;
}

void CImageCache::InitInstance()
{
Instance=new CImageCache;
}

ImageChain *CImageCache::GetChain(CString &str)
{
int i;
for(i=0;i<ImgTot && str.CompareNoCase(ISet[i]->GetImage()->GetFileName());i++) ;
if(i<ImgTot) 
	return ISet[i];
else
{
	ISet[ImgTot]=new ImageChain;
	ISet[ImgTot]->LoadImg(str);		
	ImgTot++;
	return ISet[ImgTot-1];
}
}

void CImageCache::SaveCache(CString fname)
{
FILE *fl;
fl=fopen(fname,"wb");
ASSERT(fl);
SaveCache(fl);
fclose(fl);
}

void CImageCache::LoadCache(CString fname)
{
FILE *fl;
fl=fopen(fname,"rb");
if(!fl) return;		//never crash because of the Cache
LoadCache(fl);
fclose(fl);
}

void CImageCache::SaveCache(FILE *fl)
{
char tag[7]="IMGCHE";
char ver[4]="1.0";

fwrite(tag,6,1,fl);
fwrite(ver,3,1,fl);

fwrite(&ImgTot,4,1,fl);

for(int i=0;i<ImgTot;i++)
{
ISet[i]->SaveChain(fl);
}


}

void CImageCache::LoadCache(FILE *fl)
{
char tag[7];
char ver[4];

fread(tag,6,1,fl);
fread(ver,3,1,fl);

fread(&ImgTot,4,1,fl);

ImageChain *icn;
for(int i=0;i<ImgTot;i++)
{
icn=new ImageChain;
icn->LoadChain(fl);
ISet[i]=icn;
}

}

BOOL CImageCache::LoadNextImage(int x,int y)
{
for(int idx=0;idx<ImgTot;idx++)
{
if(ISet[idx]->GetPrvImage()==NULL) 
	{
	ISet[idx]->BuildPrvImg(x,y);
	return TRUE;
	}
}

return FALSE;
}

