/************ Camera commands ************/

/***** get_num_pics() - returns the number of pictures stored in the camera *****/
get_num_pics()
{
	unsigned char txbuf[4],rxbuf[8];
	int chars_received;

	if (debug & 32) printf("»»Get number of images : result =");
	txbuf[0]=0x00;	txbuf[1]=0x0b;	txbuf[2]=0x00;	txbuf[3]=0x00;
	sendpacket(txbuf,4);	chars_received=receivepacket(rxbuf,8);
	if (chars_received != 2) {	if (debug & 32) printf("ERROR!\n"); return(0); }
	if (debug & 32) printf(" %d\n",rxbuf[0] + 256 * rxbuf[1]);
	return( rxbuf[0] + 256 * rxbuf[1] );
}

/***** get_image_size(image no) - returns the size of an image in the camera *****/
get_image_size(int imageno)
{
	unsigned char txbuf[8],rxbuf[10];
	int chars_received;

	if (debug & 32) printf("»»Get size of image %d : result =",imageno);
	txbuf[0]=0x00;				
	txbuf[1]=0x17;					/* command */
	txbuf[2]=0x02; txbuf[3]=0x00;		/* length of data being sent with command (lo/hi bytes) */
	txbuf[4]=imageno & 0xff;
	txbuf[5]=imageno >>8;
	sendpacket(txbuf,6);
	chars_received=receivepacket(rxbuf,9);
	if (chars_received != 4)
	{	if (debug &32) printf("!!Error\n"); return(0);}
	return( rxbuf[0] + (rxbuf[1]<<8) + (rxbuf[2]<<16) + (rxbuf[3]<<24) );
}

get_image_name(int imageno, char *rxbuf)
{
	unsigned char txbuf[8];
	int chars_received;

	if (debug & 32) printf("»»Get name of image %d :",imageno);
	txbuf[0]=0x00;				
	txbuf[1]=0x0a;					/* command */
	txbuf[2]=0x02; txbuf[3]=0x00;		/* length of data being sent with command (lo/hi bytes) */
	txbuf[4]=imageno & 0xff;
	txbuf[5]=imageno >>8;
	sendpacket(txbuf,6);
	chars_received=receivepacket(rxbuf,55);
	if (chars_received < 2)
	{	if (debug &32) printf("!!Error\n"); return(0);}
	rxbuf[chars_received]=NULL;
	if (debug & 32) printf(" result =%s\n", rxbuf);
	return(1);
}

get_image_info(int imageno, char *rxbuf)
{
	unsigned char txbuf[8];
	int chars_received;

	if (debug & 32) printf("»»Get info for image %d :",imageno);
	txbuf[0]=0x00;				
	txbuf[1]=0x00;					/* command */
	txbuf[2]=0x02; txbuf[3]=0x00;		/* length of data being sent with command (lo/hi bytes) */
	txbuf[4]=imageno & 0xff;
	txbuf[5]=imageno >>8;
	sendpacket(txbuf,6);
	chars_received=receivepacket(rxbuf,10000);
	if (chars_received < 1)
	{	if (debug &32) printf("!!Error\n"); return(0);}
	rxbuf[chars_received]=NULL;
	if (debug & 32) printf(" result =%s\n", rxbuf);
	return(chars_received);
}

/***** send_image(filename on disk, name on camera) - uploads image to camera *****/
#define MEMALLOC (1024*1024)
send_image(char * filename, char * imagename)
{
	unsigned char *image;
	int filesize=0;	
	FILE *fp;
	unsigned char command[4];
	char buff[255];
	int i;

	printf("»» Send image %s to camera image %s\n",filename,imagename);

	/* allocate memory for the image */
	image = (unsigned char *)calloc(MEMALLOC,1);
	if (image==NULL) return(0*printf("!! Could not allocate memory\n"));

	/* read in the image file */
	fp=fopen(filename,"r");
	if (fp == NULL) {free(image); printf("!! Could not load %s\n",filename);}
	filesize=fread(image, 1, MEMALLOC,fp);
	fclose(fp);
	printf("   Filesize=%d\n",filesize);

	/* send the image name to the camera */
	/* Set the name for picture to upload */
	buff[0]=0;
	buff[1]=0x0f;
	buff[2]=strlen(imagename);
	buff[3]=0;
	for (i=0; i<strlen(imagename); i++)
		buff[4+i]=imagename[i];
	printhex("Name> ",buff,4+strlen(imagename));
	printascii("Name> ",buff,4+strlen(imagename));
	sendpacket(buff,4+strlen(imagename));
	receivepacket(buff,10);
	printhex("Resp<",buff,16);
	printascii("Resp<",buff,16);

	/* send the image */
	command[0]=0; command[1]=0x0e; command[2]=0; command[3]=0;
	senddata(image,command,filesize+4);

	free (image);

	return(1);
}
	
	


/***** get_image(image no, filename to save) - downloads an image from camera to disk file *****/
get_image(int image_no,char *filename)
{
	unsigned char txbuf[8], *rxbuf;
	int chars_received;
	int image_size;
	FILE *fp;	

	image_size=get_image_size(image_no);
	if (!image_size) return(0*printf("!!Image %d contains no picture to download into %s\n",image_no,filename));

	if (debug & 32) printf("»»Download image %d ",image_no);

	rxbuf=(unsigned char *)calloc(image_size+2000,1);
	if (!rxbuf) return(0*printf("!!Could not allocate %d bytes for downloading image %d into %s\n",image_size,image_no,filename));

	fp=fopen(filename,"w");
	if (!fp) 
	{
		printf("!!Could not open file %s for saving image %d\n",filename,image_no);
		if (rxbuf) free(rxbuf);
		return(0);
	}

	txbuf[0]=0x00;				
	txbuf[1]=0x02;					/* command */
	txbuf[2]=0x02; txbuf[3]=0x00;		/* length of data being sent with command (lo/hi bytes) */
	txbuf[4]=image_no & 0xff;
	txbuf[5]=image_no >>8;
	sendpacket(txbuf,6);

	chars_received=receivepacket(rxbuf,image_size+1000);
	if (chars_received != image_size)
		printf("!!Error in image size: only %d out of expected %d characters received\n",chars_received,image_size);

	fwrite( rxbuf, image_size,1,fp);

	if (debug &32) printf("   : result =OK\n");

	fclose(fp);
	free(rxbuf);
	return(chars_received);
}



/***** get_thumbnail(image no, filename to save) - downloads an image from camera to disk file *****/
get_thumbnail(int image_no,char *filename)
{
	unsigned char txbuf[8], *rxbuf;
	int chars_received;
	int image_size;
	FILE *fp;	

	image_size=get_image_size(image_no);
	if (!image_size) return(0*printf("!!Image %d contains no picture to download into %s\n",image_no,filename));

	if (debug & 32) printf("»»Download image %d ",image_no);

	rxbuf=(unsigned char *)calloc(image_size+2000,1);
	if (!rxbuf) return(0*printf("!!Could not allocate %d bytes for downloading image %d into %s\n",image_size,image_no,filename));

	fp=fopen(filename,"w");
	if (!fp) 
	{
		printf("!!Could not open file %s for saving image %d\n",filename,image_no);
		if (rxbuf) free(rxbuf);
		return(0);
	}

	txbuf[0]=0x00;				
	txbuf[1]=0x00;					/* command */
	txbuf[2]=0x02; txbuf[3]=0x00;		/* length of data being sent with command (lo/hi bytes) */
	txbuf[4]=image_no & 0xff;
	txbuf[5]=image_no >>8;
	sendpacket(txbuf,6);

	chars_received=receivepacket(rxbuf,image_size+1000);
	if (chars_received < 500)
		printf("!!Error in image size: only %d out of expected %d characters received\n",chars_received,image_size);

	fwrite( rxbuf, chars_received,1,fp);

	if (debug &32) printf("   : result =OK\n");

	fclose(fp);
	free(rxbuf);
	return(chars_received);
}



/***** shoot(int *frame,int * status) shoot a picture - returns frame number and status in supplied pointers. Frame also in return value*****/
shoot(int *frame,int * status)
{
	unsigned char txbuf[8],rxbuf[10];
	int chars_received;

	if (debug & 32) printf("»»Shoot a picture : ");
	txbuf[0]=0x00;				
	txbuf[1]=0x27;					/* command */
	txbuf[2]=0x00; txbuf[3]=0x00;		/* length of data being sent with command (lo/hi bytes) */
	sendpacket(txbuf,4);
	chars_received=receivepacket(rxbuf,9);
	if (chars_received != 4)
	{	if (debug &32) printf("!!Error\n"); return(0);}

	*frame = rxbuf[0] + (rxbuf[1]<<8); *status = rxbuf[2] + (rxbuf[3]<<3);

	if (debug & 32) printf("result : frame=%d  status=%04x\n",*frame,*status);
	return( *frame);
}

charge_flash(int brightness)
{
	unsigned char txbuf[8],rxbuf[10];
	int chars_received,a;

	if (debug & 32) printf("»»Charge flash %d ",brightness);
	txbuf[0]=0x00;
	txbuf[1]=0x34;					/* command */
	txbuf[2]=0x02; txbuf[3]=0x00;		/* length of data being sent with command (lo/hi bytes) */
	txbuf[4]=brightness & 0xff;
	txbuf[5]=brightness >>8;
	sendpacket(txbuf,6);
	chars_received=receivepacket(rxbuf,9);
	if (chars_received != 1)
	{	if (debug &32) printf("!!Error\n"); return(0);}
	printf(": result =%d\n",a=rxbuf[0]);
	return( (int)rxbuf[0] );
}



/***** shoot_preview(filename)  - takes a preview shot and downloads it to filename *****/
shoot_preview( char *filename)
{
	unsigned char txbuf[8], *rxbuf;
	int chars_received;
	int image_size=50000;		/* dont have any idea really how much this should be */
	FILE *fp;	

	if (debug & 32) printf("»»Shoot and download preview to %s ",filename);

	rxbuf=(unsigned char *)calloc(image_size+2000,1);
	if (!rxbuf) return(0*printf("!!Could not allocate %d bytes for downloading preview into %s\n",image_size,filename));

	fp=fopen(filename,"w");
	if (!fp) 
	{
		printf("!!Could not open file %s for saving preview\n",filename);
		if (rxbuf) free(rxbuf);
		return(0);
	}

	/* shoot the preview */
	txbuf[0]=0x00;				
	txbuf[1]=0x64;					/* command */
	txbuf[2]=0x00; txbuf[3]=0x00;		/* length of data being sent with command (lo/hi bytes) */
	sendpacket(txbuf,4);

	chars_received=receivepacket(rxbuf,10);
	if (chars_received != 2)
		printf("!!Error in shooting preview\n");

	/* download the preview */
	txbuf[0]=0x00;				
	txbuf[1]=0x62;					/* command */
	txbuf[2]=0x00; txbuf[3]=0x00;		/* length of data being sent with command (lo/hi bytes) */
	sendpacket(txbuf,4);

	chars_received=receivepacket(rxbuf,image_size);
	printf("  Received preview of size %d\n",chars_received);

	fwrite( rxbuf, chars_received,1,fp);

	if (debug &32) printf("   : result =OK\n");

	fclose(fp);
	free(rxbuf);
	return(chars_received);
}


/***** set_flashmode(mode) - sets the flash mode *****/
set_flashmode(int mode)
{
	unsigned char txbuf[8],rxbuf[10];
	int chars_received;

	if (debug & 32) printf("»»Set flashmode to %d :",mode);
	txbuf[0]=0x00;				
	txbuf[1]=0x32;					/* command */
	txbuf[2]=0x01; txbuf[3]=0x00;		/* length of data being sent with command (lo/hi bytes) */
	txbuf[4]=mode;
	sendpacket(txbuf,5);
	chars_received=receivepacket(rxbuf,6);
	if (chars_received != 1)
	{	if (debug &32) printf("!!Error\n"); return(0);}
	if (debug & 32) printf(" result=%d\n",(int)rxbuf[0]);
	return( (int)rxbuf[0]);
}



/***** delete_image(image no) - returns the size of an image in the camera *****/
delete_image(int imageno)
{
	unsigned char txbuf[8],rxbuf[10];
	int chars_received;

	if (debug & 32) printf("»»Delete image %d :",imageno);
	txbuf[0]=0x00;				
	txbuf[1]=0x19;					/* command */
	txbuf[2]=0x02; txbuf[3]=0x00;		/* length of data being sent with command (lo/hi bytes) */
	txbuf[4]=imageno & 0xff;
	txbuf[5]=imageno >>8;
	sendpacket(txbuf,6);
	chars_received=receivepacket(rxbuf,9);
	if (chars_received != 1 || rxbuf[0])
	{	if (debug &32) printf("!!Error\n"); return(0);}
	if (debug & 32) printf("result = OK\n");
	return( 1 );
}

/***** getcommand(command) - get command info byte *****/
getcommandinfo(int command)
{
	unsigned char txbuf[8],rxbuf[10];
	int chars_received;

	if (debug & 32) printf("»»Get command info for %02x : ",command);
	txbuf[0]=0x00;
	txbuf[1]=0x51;					/* command */
	txbuf[2]=0x01; txbuf[3]=0x00;		/* length of data being sent with command (lo/hi bytes) */
	txbuf[4]=command;
	sendpacket(txbuf,5);
	chars_received=receivepacket(rxbuf,9);
	if (chars_received != 2)
	{	if (debug &32) printf("!!Error\n"); return(0);}

	printf("&Command %02x -> %02x %02x\n",command,(int)rxbuf[0],(int)rxbuf[1]);
	return( rxbuf[0] + (rxbuf[1]<<8)  );
}

#define BAUDRATE 57600
#define BAUD_SEL 7
setup_comm()
{
	unsigned char buffer[512];
	int show=0;

     if (debug & 128) show=1;

	if (debug & 128) printf(">Trying to establish contact at %d\n",BAUDRATE);
	openserial(BAUDRATE);
	flushserial(buffer,512,show);
	sendchar(0x05);
	sendchar(0x05);
	Delay(5);
	flushserial(buffer,512,show);
	if (buffer[0]==0x6 && buffer[1]==0x6)
	{
		if(debug & 128) printf(" >Speed already %d\n",BAUDRATE);
		return(1);
	}


	if (debug & 128) printf(" >Failed at %d\n>Trying to establish contact at 9600\n",BAUDRATE);
	closeserial();
	openserial(9600);
	flushserial(buffer,512,show);
	sendchar(0x05);
	sendchar(0x05);
	flushserial(buffer,512,show);
	if (buffer[0]==0x06 && buffer[1]==0x06)
     	if (debug & 128) printf(" >Connected succesfully at 9600\n");
	else
	{
		if (debug & 128) printf(" >FAILED\n");
		return(0);
	}

	if (debug & 128) printf(">Sending speed change command to camera\n");
	sendchar(0x10);
	sendchar(0x02);
		sendchar(0x01);
		sendchar(0x07);
		sendchar(0x01);
		sendchar(0x00);
 		sendchar(BAUD_SEL);
	sendchar(0x10);
	sendchar(0x03);
	sendchar(1^7^1^0^BAUD_SEL^3);

	Delay(5);
	flushserial(buffer,512,show);
	if (buffer[0]=0x6)
		if (debug & 128) printf(" >Command acknowledged\n");
	else
	{
		if (debug & 128) printf(" >FAILED\n");
		return(0);
	}

	sendchar(0x06);
	flushserial(buffer,512,show);

	if (debug &128) printf(">Closing connection\n");
	sendchar(0x04);
	closeserial();

	Delay(5);

	if (debug & 128) printf(">Trying to re-establish contact at %d\n",BAUDRATE);
	openserial(BAUDRATE);
	flushserial(buffer,512,show);
	sendchar(0x05);
	sendchar(0x05);
	flushserial(buffer,512,show);
	if (buffer[0]==0x6 && buffer[1]==0x6)
	{
		if (debug & 128) printf(" >Connected succesfully at %d\n",BAUDRATE);
		return(1);
	}
	else
	{
		if (debug & 128) printf(" >FAILED\n");
		return(0);
     }
	return(1);
}
