#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include "match.h"
#include "util.h"


struct cryst
{
    char *space_group, *a, *b, *c;
    char *alpha, *beta, *gamma;
}cell_unit;


struct coord
{
    char **group_pdb, **atomnum, **atomname, **alt;
    char **resname, **chainID, **resnum, **x;
    char **y, **z, **occup, **biso, **footnote;
    char **auth_asym, **pdbx_PDB_model_num;
    
}xyz;

extern char METHOD[10];

int strcmp_case (const char *s1, const char *s2);
int strncmp_case (const char *s1, const char *s2, int n);


void cif2pdb(char *iFile, char *oFile)
{

    int i=0,  j=0;
    long n0=0,n1=0,n2=0,n3=0,n4=0,n5=0,n6=0;
    long n7=0,n8=0,n9=0, n10=0, n11=0, n12=0;
    char *diags=NULL, *blockId=NULL, fnx[10]="cif2pdbte";

    CifFileObj * fobjR = NULL;
    FILE *fp, *fout;
    
    if((fp = fopen(iFile, "r"))==NULL){        
        printf("Can not open the file %s (routine:is_category)\n",iFile);
        return ;
    }
    if((fout = fopen(oFile, "w"))==NULL){        
        printf("Can not write the file %s (routine:is_category)\n",oFile);
        return ;
    }

  
    fobjR = new CifFileObj(fnx, WRITE_MODE, 80, "?", 1);
    fobjR->Read(iFile,diags);
    if (diags != NULL) {
        fprintf(stderr, "Diags for file %s: %s\n",iFile,diags);
//        exit(0);
    }
    
    fobjR->CloseFile();
    if (fobjR) delete fobjR;


    fobjR = new CifFileObj(fnx, READ_MODE);
    blockId = fobjR->GetBlockName(0);

    xyz.group_pdb=get_attribute_values(fobjR,blockId,"atom_site", "group_PDB", &n1);
    xyz.atomnum = get_attribute_values(fobjR, blockId, "atom_site", "id", &n2);
    xyz.atomname = get_attribute_values(fobjR, blockId, "atom_site", "label_atom_id", &n3);
    xyz.alt = get_attribute_values(fobjR, blockId, "atom_site", "label_alt_id", &n4);
    xyz.resname = get_attribute_values(fobjR, blockId, "atom_site", "label_comp_id", &n5);
    xyz.chainID = get_attribute_values(fobjR, blockId, "atom_site", "label_asym_id", &n6);
    xyz.resnum = get_attribute_values(fobjR, blockId, "atom_site", "auth_seq_id", &n7);
    xyz.x = get_attribute_values(fobjR, blockId, "atom_site", "Cartn_x", &n8  );
    xyz.y = get_attribute_values(fobjR, blockId, "atom_site", "Cartn_y", &n9  );
    xyz.z = get_attribute_values(fobjR, blockId, "atom_site", "Cartn_z", &n10 );
    xyz.occup = get_attribute_values(fobjR, blockId, "atom_site", "occupancy", &n11 );
    xyz.biso = get_attribute_values(fobjR, blockId, "atom_site", "B_iso_or_equiv", &n12 );
    xyz.pdbx_PDB_model_num = get_attribute_values(fobjR, blockId, "atom_site", "pdbx_PDB_model_num", &n0);


    if(n8<1 && n9<1 && n10<1) {
        printf("mmCIF to PDB conversion error!\n");
        exit(0);
    }
    
    if(strcmp_case(METHOD, "NMR")){
        cell_unit.a = get_attribute_value(fobjR, blockId, "cell", "length_a");
        cell_unit.b = get_attribute_value(fobjR, blockId, "cell", "length_b");
        cell_unit.c = get_attribute_value(fobjR, blockId, "cell", "length_c");
        cell_unit.alpha = get_attribute_value(fobjR, blockId, "cell", "angle_alpha");
        cell_unit.beta = get_attribute_value(fobjR, blockId, "cell", "angle_beta");
        cell_unit.gamma = get_attribute_value(fobjR, blockId, "cell", "angle_gamma");
        cell_unit.space_group = get_attribute_value(fobjR, blockId, "symmetry", "space_group_name_H-M");
    

        if(cell_unit.a && cell_unit.b && cell_unit.c && cell_unit.alpha && cell_unit.beta && cell_unit.gamma){
            if(cell_unit.space_group){
                fprintf(fout,"CRYST1%9s%9s%9s%7s%7s%7s %10s  \n", cell_unit.a , cell_unit.b , cell_unit.c ,
                        cell_unit.alpha , cell_unit.beta , cell_unit.gamma, cell_unit.space_group);
            }else
                fprintf(fout,"CRYST1%9s%9s%9s%7s%7s%7s  \n", cell_unit.a , cell_unit.b , cell_unit.c ,
                        cell_unit.alpha , cell_unit.beta , cell_unit.gamma);
        }

    }
        
        

      
  for(i=0; i<n8; i++){
      if(n0>1)j=atoi(xyz.pdbx_PDB_model_num[i]);
      if(n0>1 && j!=1) continue;
      
      (n1>0) ? fprintf(fout,"ATOM  ") :  fprintf(fout,"ATOM  ");
      (n2>0) ? fprintf(fout,"%5s ", xyz.atomnum[i])  : fprintf(fout,"%5s ", " ");

      if((n3>0 && strlen(xyz.atomname[i])==4 ) ){
          (n3>0 && strlen(xyz.atomname[i])==4 )
              ? fprintf(fout,"%4s", xyz.atomname[i])  : fprintf(fout,"%4s", " ");
      }else if((n3>0 && strlen(xyz.atomname[i])==3 ) ){
          (n3>0 && strlen(xyz.atomname[i])==3 )
              ? fprintf(fout," %3s", xyz.atomname[i])  : fprintf(fout,"%4s", " ");
          
      }else if((n3>0 && strlen(xyz.atomname[i])==2 ) ){
          (n3>0 && strlen(xyz.atomname[i])==2 )
              ? fprintf(fout," %2s ", xyz.atomname[i])  : fprintf(fout,"%4s", " ");
          
      }else if((n3>0 && strlen(xyz.atomname[i])==1 ) ){
          (n3>0 && strlen(xyz.atomname[i])==1 )
              ? fprintf(fout," %1s  ", xyz.atomname[i])  : fprintf(fout,"%4s", " ");
          
      }
      
      (n4>0 && xyz.alt[i][0] !='.' && xyz.alt[i][0] !='?' )
          ? fprintf(fout,"%1s", xyz.alt[i])  : fprintf(fout,"%1s", " ");
      (n5>0) ? fprintf(fout,"%3s ", xyz.resname[i])  : fprintf(fout,"%4s", " ");
      (n6>0 && xyz.chainID[i][0] !='.' && xyz.chainID[i][0] !='?' )
          ? fprintf(fout,"%1s", xyz.chainID[i])  : fprintf(fout,"%1s", " ");
          
      if (n7>0 && strlen(xyz.resnum[i])<=4 ){
          (n7>0 && strlen(xyz.resnum[i])<=4 )
              ? fprintf(fout,"%4s ",xyz.resnum[i]) : fprintf(fout,"%5s", " ");
      }else if (n7>0 && strlen(xyz.resnum[i])>4 ){
          (n7>0 && strlen(xyz.resnum[i])>4 )
              ? fprintf(fout,"%5s",xyz.resnum[i])  : fprintf(fout,"%5s", " ");
      }
      
      (n8>0 && n9>0 && n10>0)
          ? fprintf(fout,"   %8s%8s%8s", xyz.x[i], xyz.y[i], xyz.z[i])  : fprintf(fout,"%29s", " ");
       
      (n11>0&& n12>0) ? fprintf(fout,"%6s%6s",  xyz.occup[i], xyz.biso[i]): fprintf(fout,"%12s", " ");
 
  fprintf(fout,"\n");
      
  }
  fclose(fp);
  fclose(fout);
  if (fobjR) delete fobjR;
  delete_file(fnx);
  

}




           
