/******************************************************************************/
/*Program: pdbconv-whatif2amber                                                           */
/*Author: Stefan Henrich                                                      */ 
/*Email:  stefan.henrich@eml-r.villa-bosch.de                                 */
/*Date: 20.01.2005  version 2.02                                              */
/*                                                                            */
/*Purpose: convert of whatif output pdb files for AMBER                       */
/*                                                                            */
/*COMPILATION: cc -o pdbconv-whatif2amber pdbconv-whatif2amber.c              */
/*USAGE: >pdbconv whatifout.pdb whatif2amber.pdb ligandname                   */
/*USAGE: >pdbconv-whatif2amber 1ejn.modifnew.pdb 1ejn.whatifout.tmp.pdb A25   */
/******************************************************************************/

#include <stdio.h>
#include <string.h>

int main (
	int argc,         /* Number of args */
	char ** argv)     /* Arg list       */
{
	FILE *finput,*foutput,*foutput2,*fcyxin;
    char line[120],newline[120],templine[120],templine2[120],ssbond[200],hdeline[120];
	char buffer[4],fill[]="    ",resinew[]="      ",resiold[]="      ",atomold[]="      ";
	int mark=0,a=0,aa=0,b=0,bb=0;
	int cyxresi[40],cyxnumb=0; //array for cyx residue numbers, counter for array
	char cyx[150],cyxtemp[]="     "; //string for storing fcyxin,substring of cyx
	
	if((finput = fopen(argv[1] , "r"))==NULL)
	  {printf("Input file can not be opened .\n");exit(0);}
	if((foutput = fopen("RENUMBTMP.PDB", "w"))==NULL)
	  {printf("Temp file RENUMBTMP.PDB can not be written .\n");exit(0);}
	if((foutput2 = fopen(argv[2], "w"))==NULL)
	  {printf("OUT File  can not be written .\n");exit(0);}
	if((fcyxin = fopen("CYX-RESIDUES.TMP", "r"))==NULL)
	  {printf("CYX-RESIDUES.TMP File can not be read.\n");exit(0);}

	  printf("pdbconv version 2.10\nconverting whatif pdb file for xleap\n\n");
	  
////////////////////////////////////////////////////////
// STARTING WITH PDB
	while(fgets(line,100,finput)){/*printf("%s",line);*/
		strncpy(templine,line,99);
		strncpy(templine2,line,99);
		strncpy(resinew,line+22,4); //get string of residue number 
		
// RENAMING HYDROGENS OF WATER
		if(strncmp(line+13,"O",1)!=0 && strncmp(line+17,"HOH",3)==0)
		{  
			strncpy(newline,templine,12);newline[12]='\0';
			if (mark==0) {	
				strcat(newline," H1 ");strncat(newline,templine+16,1);strcat(newline,"HOH"); mark=1;}
			else {strcat(newline," H2 ");strncat(newline,templine+16,1);strcat(newline,"HOH"); mark=0;}
			strncat(newline,templine+20,46);
			strncpy(templine,newline,66);
	   	}

// RENAMING HYDROGENS OF PROTEIN
//		if(strcmp(resinew,resiold)!=0) hydrogen=1; //start hydrogen numbering for new residue with H1
		if(strncmp(line,"ATOM  ",4)==0 && strncmp(line+17,"HOH",3)!=0 && strncmp(line+17,argv[3],3)!=0 &&
			strncmp(line+17,"CAA",3)!=0 && strncmp(line+17,"Cl-",3)!=0 && 
			strncmp(line+13,"C",1)!=0 && strncmp(line+13,"O",1)!=0 && 
			strncmp(line+13,"N",1)!=0 && strncmp(line+13,"S",1)!=0 )
		{  
			strncpy(newline,line,12);newline[12]='\0';
//			sprintf(buffer,"%d",hydrogen); //copy hydrogen into buffer
			strncat(buffer,fill,4); //add blank to buffer
			
			if(strncmp(atomold," N  ",4)==0) {strncpy(buffer," H  ",4);} //N
			if(strncmp(atomold," ND1",4)==0) {strncpy(buffer," HD1",4);} //HIS
			if(strncmp(atomold," NE2",4)==0 && strncmp(line+17,"HIS",3)==0) {strncpy(buffer," HE2",4);} //HIS
			if(strncmp(atomold," ND2",4)==0 && strncmp(line+17,"ASN",3)==0) {strncpy(buffer,"HD21",4);} //ASN
			if(strncmp(atomold,"HD21",4)==0 && strncmp(line+17,"ASN",3)==0) {strncpy(buffer,"HD22",4);} //ASN
			if(strncmp(atomold," NE2",4)==0 && strncmp(line+17,"GLN",3)==0) {strncpy(buffer,"HE21",4);} //GLN
			if(strncmp(atomold,"HE21",4)==0) {strncpy(buffer,"HE22",4);} //GLN
			if(strncmp(atomold," NE ",4)==0) {strncpy(buffer," HE ",4);} //ARG
			if(strncmp(atomold," NH1",4)==0) {strncpy(buffer,"HH11",4);} //ARG
			if(strncmp(atomold,"HH11",4)==0) {strncpy(buffer,"HH12",4);} //ARG
			if(strncmp(atomold," NH2",4)==0) {strncpy(buffer,"HH21",4);} //ARG
			if(strncmp(atomold,"HH21",4)==0) {strncpy(buffer,"HH22",4);} //ARG
			if(strncmp(atomold," NZ ",4)==0) {strncpy(buffer," HZ1",4);} //LYS
			if(strncmp(atomold," HZ1",4)==0) {strncpy(buffer," HZ2",4);} //LYS
			if(strncmp(atomold," HZ2",4)==0) {strncpy(buffer," HZ3",4);} //LYS
			if(strncmp(atomold," NE1",4)==0) {strncpy(buffer," HE1",4);} //TRP
			if(strncmp(atomold," OD1",4)==0) {strncpy(buffer," HD1",4);} //ASP
			if(strncmp(atomold," OD2",4)==0) {strncpy(buffer," HD2",4);} //ASP
			if(strncmp(atomold," OE1",4)==0) {strncpy(buffer," HE1",4);} //GLU
			if(strncmp(atomold," OE2",4)==0) {strncpy(buffer," HE2",4);} //GLU
			if(strncmp(atomold," OG1",4)==0) {strncpy(buffer," HG1",4);} //THR
			if(strncmp(atomold," OG ",4)==0) {strncpy(buffer," HG ",4);} //SER
			if(strncmp(atomold," OH ",4)==0) {strncpy(buffer," HH ",4);} //TYR
			if(strncmp(atomold," N  ",4)==0 && strncmp(line+21,"    1",5)==0) {strncpy(buffer," H1 ",4);} //N-TERM
			if(strncmp(atomold," H1 ",4)==0) {strncpy(buffer," H2 ",4);} //N-TERM
			if(strncmp(atomold," H2 ",4)==0) {strncpy(buffer," H3 ",4);} //N-TERM
			
//			printf("%s\n",buffer);
			strncat(newline,buffer,4);			
			strncat(newline+16,line+16,51);
			strncpy(templine,newline,66); 
//			strncpy(templine2,newline,66); 
//			hydrogen=hydrogen+1;	
//			strcpy(resiold,resinew); //store residue number for next cycle
	   	}
			strncpy(atomold,templine+12,4); //store atom type for next cycle
//			printf("%s",atomold);
	fprintf(foutput,"%s",templine); 
	} /* end of while */

////////////////////////////////////////////////////////
// SSBOND CYS -> CYX
//read CYX residue numbers from fcyxin (CYX-RESIDUES.TMP) and store it into cyxresi[cyxnumb]
		fgets(cyx,100,fcyxin); /*printf("%s",cyx);*/
		while(strlen(cyx)>=(cyxnumb*4+4))
		{
			cyxresi[cyxnumb]=atoi(strncpy(cyxtemp,cyx+cyxnumb*4,4));
			cyxnumb=cyxnumb+1;
		}
////////////////////////////////////////////////////////

fclose(foutput);
foutput = fopen("RENUMBTMP.PDB", "r");

////////////////////////////////////////////////////////
// STARTING WITH PDB

	while(fgets(line,100,foutput)){
//		printf("%s",line);
		strncpy(templine,line,99);
		strncpy(resinew,line+22,4); //get string of residue number 

// SSBOND CYS -> CYX
		if((strncmp(line+17,"CYS",3)==0) && (strncmp(line,"ATOM  ",6)==0))	{ 
			for(cyxnumb=0;(cyxnumb*4+4)<=strlen(cyx);cyxnumb++)
			{
				if(cyxresi[cyxnumb]==atoi(resinew))	{	
					strncpy(newline,templine,17);newline[17]='\0';
					strncat(newline,"CYX",3);
					strncat(newline+20,templine+20,46);
					strncpy (templine,newline,66);			
				} // end of if
			} // end of for
		} 


// HIS -> HID, HIE, HIP
//	The residues musn't be separated! (eg. no remark-lines within a residue)
		if((strncmp(line+17,"HIS",3)==0) && (strncmp(line,"ATOM  ",6)==0))	{  
			int hde=0,address;
			char hydrotempline[120];
        	int HYDROGEN(char hydroline[120], int kk)
			{
				if((strncmp(hydroline+13,"HD1",3)==0) && (strncmp(line+17,"HIS",3)==0))   kk=kk+1;  
				if((strncmp(hydroline+13,"HE2",3)==0) && (strncmp(line+17,"HIS",3)==0))   kk=kk+2; 
				fgets(hydroline,100,foutput);
				if(strncmp(hydroline+17,"HIS",3)!=0) return kk; 
				else	HYDROGEN(hydroline, kk); 
			} // end of HYDROGEN

			address=ftell(foutput); //get current address of line
			hde=HYDROGEN(line,a); //start function HYDROGEN
			fseek(foutput,address,SEEK_SET); //back to current pointer of line 
			if(hde>=aa) aa=hde;
			if(aa==0){  
				strncpy(newline,templine,17);newline[17]='\0';
				strncat(newline,"HIS",3);
				strncat(newline+20,templine+20,46);
				strncpy (templine,newline,66);} else
			if(aa==1){  
				strncpy(newline,templine,17);newline[17]='\0';
				strncat(newline,"HID",3);
				strncat(newline+20,templine+20,46);
				strncpy (templine,newline,66);} else
			if(aa==2){  
				strncpy(newline,templine,17);newline[17]='\0';
				strncat(newline,"HIE",3);
				strncat(newline+20,templine+20,46);
				strncpy (templine,newline,66);} else
			if(aa>2){  
				strncpy(newline,templine,17);newline[17]='\0';
				strncat(newline,"HIP",3);
				strncat(newline+20,templine+20,46);
				strncpy (templine,newline,66);}
//		detect end of residue HIS
			fgets(hdeline,100,foutput); 
			if(strncmp(hdeline+17,"HIS",3)!=0) aa=0; 
			fseek(foutput,address,SEEK_SET); //back to current pointer of line
			
		} // end of if his

//--ASP, ASH (name of HD2 in original pdf-file unclear (no example could be found))
//	The residues musn't be separated! (eg. no remark-lines within a residue)
		if((strncmp(line+17,"ASP",3)==0) && (strncmp(line,"ATOM  ",6)==0))	{  
			int hde=0,address;
			char hydrotempline[120];
        	int HYDROGEN(char hydroline[120], int kk)
			{
				if((strncmp(hydroline+13,"HD2",3)==0) && (strncmp(line+17,"ASP",3)==0))   kk=kk+1;  
				fgets(hydroline,100,foutput);
				if(strncmp(hydroline+17,"ASP",3)!=0) return kk; 
				else	HYDROGEN(hydroline, kk); 
			} 

			address=ftell(foutput); //get current address of line
			hde=HYDROGEN(line,b); //start function HYDROGEN
			fseek(foutput,address,SEEK_SET); //back to current pointer of line 
			if(hde>=bb) bb=hde;
			if(bb==0){  
				strncpy(newline,templine,17);newline[17]='\0';
				strncat(newline,"ASP",3);
				strncat(newline+20,templine+20,46);
				strncpy (templine,newline,66);} else
			if(bb==1){  
				strncpy(newline,templine,17);newline[17]='\0';
				strncat(newline,"ASH",3);
				strncat(newline+20,templine+20,46);
				strncpy (templine,newline,66);} else
//		detect end of residue ASP
			fgets(hdeline,100,foutput); 
			if(strncmp(hdeline+17,"ASP",3)!=0) bb=0; 
			fseek(foutput,address,SEEK_SET); //back to current pointer of line
		}  // end of if ASP

// C-terminal oxygen is not written in pdb
		if((strncmp(line+22,"  O2",4)!=0 && strncmp(line+12," O2 ",4)!=0) &&
			(strncmp(line+17,argv[3],3)!=0))	{
			fprintf(foutput2,"%s",templine); }
//		fprintf(foutput2,"%s",templine); 
	} /* end of while */
	
	fclose(finput);
	fclose(fcyxin);
	fclose(foutput);
	fclose(foutput2);
 return(1);
}
