#include "windows.h"
#include "stdio.h"
#include "D:\Program Files\Scilab-2.7\routines\stack-c.h"
#include "time.h"
#define BW_FLAG 0
#define RGB_FLAG 1

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

/*You can use this function to show an image(true color or binary) upon the forground window     */

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

void impreview __PARAMS((char *hWnd_old, double *z,int row, int column, double flag, double dest_x, double dest_y));

int char2int(char *n_16);
double findmax(double *sci_data,int width,int height, int dims);

int xmu_impreview(char *fname)
{
	char	**Str2;
	int		*dims,lm1, ln1, ll1, lm2, 
			 ln2,ll2, lt3, lm3, ln3,  
			 ll3,lc3;
	int		m1, m2, m3,
			n1, n2, n3,
			l1, l2, l3;
	int		minlhs, maxlhs, minrhs, maxrhs;

	minlhs = 1, maxlhs = 1, minrhs = 4, maxrhs = 4;
	/* Check number of inputs (rhs=4) and outputs (lhs=1) */
	CheckRhs(minrhs, maxrhs) ;
	CheckLhs(minlhs, maxlhs) ;
	
	GetRhsVar(1,"c",&m1,&n1,&l1);
	GetRhsVar(3,"d",&m2,&n2,&l2);  
	GetRhsVar(4,"d",&m3,&n3,&l3);    

	if(VarType(2) == 1) {					// binary image
		GetRhsVar(2,"d",&lm1,&ln1,&ll1);
		if(lm1*ln1 == 0) {
			Scistring("argument 2 is not a M x N usualmatrix!\n");
			return 0;
		}
		impreview(cstk(l1), stk(ll1), lm1, ln1, 0, *stk(l2), *stk(l3));
	}
	else if(VarType(2) == 17) {				// true colormap
		GetListRhsVar(2,1,"S",&lm1,&ln1,&Str2);
		if ( strcmp(Str2[0],"hm") != 0) {
			Scistring("Argument 2 is not an hypermatrix\r\n");
			return 0;
		}
		GetListRhsVar(2,2,"i",&lm2,&ln2,&ll2);
		GetListRhsCVar(2,3,"d",&lt3,&lm3,&ln3,&ll3,&lc3);
		dims=istk(ll2);
		if (lm2*ln2 != 3) {
		Scistring("argument 2 is not a 3D hypermatrix!\n");
		return 0;
		}
		else if (dims[2] != 3) {
			Scistring("argument 2 is not a M x N x 3 hypermatrix!\n");
			return 0;
		}
		FreeRhsSVar(Str2);
		impreview(cstk(l1), stk(ll3), dims[0], dims[1], 1, *stk(l2), *stk(l3));
	}
	else {
		Scistring("argument 2 must be matrix or hypermatrix!\n");
		return 0;
	}

	LhsVar(1) = 0;
	return 0;
}
void impreview(char *hWnd_old, double *z, int row, int column, double flag, double dest_x, double dest_y)
{
	BITMAPINFO  bitmapInfo;
    int  size;
	BYTE *temp1,*temp2;
	int  nXDest,nYDest;
	int  i,j,k;
	long dwWidthBytes;
	HWND hWnd;
	HDC  hdc;
	int  ret_val, wid;
	double temp;

	wid=char2int(hWnd_old);
	hWnd=(HWND)wid;
	hdc=GetWindowDC(hWnd);
	

	memset(&bitmapInfo,0,sizeof(bitmapInfo));
	bitmapInfo.bmiHeader.biSize=40;
	bitmapInfo.bmiHeader.biPlanes=1;
	bitmapInfo.bmiHeader.biBitCount=24;
	bitmapInfo.bmiHeader.biCompression=BI_RGB;
	bitmapInfo.bmiHeader.biXPelsPerMeter=0;
	bitmapInfo.bmiHeader.biYPelsPerMeter=0;
	bitmapInfo.bmiHeader.biClrUsed=0;
	bitmapInfo.bmiHeader.biClrImportant=0;

	dwWidthBytes=(int)dest_x*3;
    while((dwWidthBytes&3)!=0) dwWidthBytes++;

	bitmapInfo.bmiHeader.biWidth=dest_x;
	bitmapInfo.bmiHeader.biHeight=dest_y;
	bitmapInfo.bmiHeader.biSizeImage=dwWidthBytes*dest_y;

	size=3*dest_x*dest_y;
	if(!(temp1=(BYTE *)malloc(size*sizeof(BYTE))))
	{
		printf("Memory unavailable!\n");
		return ;
	}

	for(i=0; i<dest_y; i++)
		for(j=0; j<dest_x; j++)
			for(k=0; k<3; k++)
				temp1[((int)dest_y-i-1)*(int)dest_x*3+j*3+k]=255;

	ret_val=StretchDIBits(hdc,0,0,(int)dest_x,(int)dest_y,
		0,0,(int)dest_x,(int)dest_y,temp1,&bitmapInfo,DIB_RGB_COLORS,SRCCOPY);
//	UpdateWindow(hWnd);

	free(temp1);

	dwWidthBytes=column*3;
    while((dwWidthBytes&3)!=0) dwWidthBytes++;

	bitmapInfo.bmiHeader.biWidth=column;
	bitmapInfo.bmiHeader.biHeight=row;
	bitmapInfo.bmiHeader.biSizeImage=dwWidthBytes*row;

	

	size=dwWidthBytes*row;
	if(!(temp2=(BYTE *)malloc(size*sizeof(BYTE))))
	{
		printf("Memory unavailable!\n");
		return ;
	}
	if(flag==RGB_FLAG)
	{   
		if(findmax(z,column,row,3)>255)
		{
			for(k=0;k<3;k++)
				for(j=0;j<column;j++)
					for(i=0;i<row;i++)
					temp2[(row-i-1)*dwWidthBytes+j*3+2-k]=(BYTE)((z[k*row*column+j*row+i]+1)/256-1);
		}
		else
		{
			for(k=0;k<3;k++)
				for(j=0;j<column;j++)
					for(i=0;i<row;i++)
					temp2[(row-i-1)*dwWidthBytes+j*3+2-k]=(BYTE)(z[k*row*column+j*row+i]);
		}
		//t equals to k*nWidth*nHeight+j*nHeight+i
	}
	
	else if(flag==BW_FLAG)
	{
		temp=findmax(z,column,row,1);
		if(temp>255)
		{
			for(j=0;j<column;j++)
				for(i=0;i<row;i++)
					for(k=0;k<3;k++)
							temp2[(row-i-1)*dwWidthBytes+j*3+k]=(BYTE)((z[j*row+i]+1)/256-1);

		}
		else if(temp>1)
		{
			for(j=0;j<column;j++)
				for(i=0;i<row;i++)
					for(k=0;k<3;k++)
							temp2[(row-i-1)*dwWidthBytes+j*3+k]=(BYTE)(z[j*row+i]);

		}
		else
		{
			for(j=0;j<column;j++)
				for(i=0;i<row;i++)
					for(k=0;k<3;k++)
							temp2[(row-i-1)*dwWidthBytes+j*3+k]=(BYTE)((z[j*row+i])*255);
		}
	}
	
	column=(column<dest_x)?column:(int)dest_x;
	row=(row<dest_y)?row:(int)dest_y;
	nXDest=(column>=dest_x)?0:(int)(dest_x-column)/2;
	nYDest=(row>=dest_y)?0:(int)(dest_y-row)/2;


	ret_val=StretchDIBits(hdc,nXDest,nYDest,column,row,
		0,0,column,row,temp2,&bitmapInfo,DIB_RGB_COLORS,SRCCOPY);
	
	UpdateWindow(hWnd);
	ReleaseDC(hWnd,hdc);
	free(temp2);
	
	if(ret_val==GDI_ERROR)
		Scistring("Display failed!\n");
	return ;  
}

int char2int(char *n_16)
{
	int n_10=0;
	int i;
	int length=strlen(n_16);
	if(length<2)
	{
		printf("the type is incorrect!\n");
		return 0;
	}
	else if(n_16[0]!='0'||n_16[1]!='x')
	{
		printf("the type is incorrect!\n");
		return 0;
	}
	else
	for(i=2;i<length;i++)
	{
		int temp;
		if(n_16[i]>='a'&&n_16[i]<='f')
			temp = n_16[i] - 'a' + 10;
		else if(n_16[i]>='A'&&n_16[i]<='F')
			temp = n_16[i] - 'A' + 10;
		else if(n_16[i]>='0'&&n_16[i]<='9')
			temp = n_16[i] - '0';

		n_10 *= 16;
		n_10 += temp;
	}
	return n_10;
}

double findmax(double *sci_data,int width,int height, int dims)
{
	long i=0;
	long size=width*height*dims;
	double max=0;

	for(i=0;i<size;i++)
	{
		if(max<sci_data[i])
			max=sci_data[i];
	}
	return max;
}
