/* $Id$ */

/*****************************************************************************
** 
**      Date: 30th October 2000
**
**	Author: Scott A. Belmonte
**
******************************************************************************
******************************************************************************
*     COUE is                                                                
*           a program that converts Crystal atomic constraints
*           into GSAS constraints in a forn that can be 
*           cut and pasted into the GSAS atom menu in EXPEDT.
*
*     Program Web-site at:                                                   
*            http://www.ccp14.ac.uk/ccp/web-mirrors/scott-belmonte-software/ 
*                                                                            
*                            Scott A. Belmonte - July 2000             
*                            s.a.belmonte@dl.ac.uk                           
*                            Department of Physics and Astronomy             
*                            University of Edinburgh                         
*                            UK.                                   
*                                                                            
******************************************************************************
******************************************************************************
*
*    Copyright (C) 2000 Scott Belmonte
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 
* 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
*
***********************************************************************/


/*
 * $Log$
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LINE_LEN 80

void output_gsas_constraints(FILE *inPtr, FILE *outPtr);
void output_topas_constraints(FILE *inPtr, FILE *outPtr);

int main(int argv, char *argc[])
{

  FILE *inPtr, *outPtr;
  char in_name[FILENAME_MAX];
  char out_name[FILENAME_MAX];
  char format_type[10];
  unsigned int ui;
  
  printf("\n");
  printf("********************************************\n");
  printf("*                COUE V1.0                 *\n");
  printf("*  Crystals to GSAS constraints converter  *\n");
  printf("*                                          *\n");
  printf("*    Released under the GNU GPL Licence    *\n");
  printf("*       (c) 2000 Scott A. Belmonte         *\n");
  printf("********************************************\n");
  printf("\n");

  printf("Enter Crystals constraints file name: ");
  scanf("%s", in_name);

  if ((inPtr = fopen(in_name, "r")) == NULL) {
    fprintf(stderr, "Error opening %s for input.\n", in_name);
    exit(1);
  }


  printf("Enter name of output file: ");
  scanf("%s", out_name);

  if ((outPtr = fopen(out_name, "w")) == NULL) {
    fprintf(stderr, "Error opening %s for output.\n", out_name);
    exit(1);
  }

  printf("Which format do you want to convert to: gsas, topas: ");
  scanf("%s", format_type);

  for (ui = 0; ui < strlen(format_type); ui++) 
    format_type[ui] = toupper(format_type[ui]);

  if (strcmp(format_type, "GSAS") == 0) {
    output_gsas_constraints(inPtr, outPtr);
  }

  if (strcmp(format_type, "TOPAS") == 0) {
    output_topas_constraints(inPtr, outPtr);
  }

  fclose(inPtr);
  fclose(outPtr);
  return 0;
}



void output_gsas_constraints(FILE *inPtr, FILE *outPtr) {

  char line[LINE_LEN], *tokenPtr;
  int err, line_num, num, found_atom_num1, found_atom_num2;
  int atom_num1, atom_num2;
  int last_atom_num1, last_atom_num2;
  double dist, tol;

  last_atom_num1 = 0; last_atom_num2 = 0; line_num = 0;
  while (fgets(line, 80, inPtr)) {
    line_num++;
    if ((strncmp(line, "DIST", 4)) == 0) {
      line[16] = '\0';
      err = sscanf(&line[4], "%lf%*c%lf", &dist, &tol);
      if (err != 2) {
	fprintf(stderr, "Error reading distance and tolerance on line %d.\n",
		line_num);
	exit(1);
      }
      tokenPtr = strtok(&line[17], " (),to");
      found_atom_num1 = 0; found_atom_num2 = 0;
      while (tokenPtr != NULL) {
	err = sscanf(tokenPtr, "%d", &num);
	if (err == 1) {
	  if (found_atom_num1 == 0) {
	    found_atom_num1 = 1;
	    atom_num1 = num;
	  } else {
	    found_atom_num2 = 1;
	    atom_num2 = num;
	    break;
	  }
	}
	tokenPtr = strtok(NULL, " (),to");
      }
      if (found_atom_num1 == 0 && found_atom_num2 == 0) {
	fprintf(stderr, "Error reading atom numbers on line %d.\n",
		line_num);
	exit(1);
      }

      if (atom_num1 == last_atom_num1 && atom_num2 == last_atom_num2) {
	fprintf(outPtr, "Y\n");
      } else {
	fprintf(outPtr, "I %f %f %d %d\nY\n", 
		dist, tol, atom_num1, atom_num2);
	last_atom_num1 = atom_num1; 
	last_atom_num2 = atom_num2;
      }
    }
  }
}


void output_topas_constraints(FILE *inPtr, FILE *outPtr) {

  char line[LINE_LEN], *tokenPtr;
  int err, line_num;
  char atom1[10], atom2[10];
  char last_atom1[10], last_atom2[10];
  int num_restraints, num_same;
  double dist, tol, last_dist, last_tol;

  last_atom1[0] = '\0'; last_atom2[0] = '\0';
  line_num = 0; num_restraints = 0; num_same = 0;
  last_dist = 0.0; last_tol = 0.0;
  while (fgets(line, 80, inPtr)) {
    line_num++;
    if ((strncmp(line, "DIST", 4)) == 0) {
      line[16] = '\0';
      err = sscanf(&line[4], "%lf%*c%lf", &dist, &tol);
      if (err != 2) {
	fprintf(stderr, "Error reading distance and tolerance on line %d.\n",
		line_num);
	exit(1);
      }
      tokenPtr = strtok(&line[17], " (),to");
      strcpy(atom1, tokenPtr);
      tokenPtr = strtok(NULL, " (),to");
      strcat(atom1, tokenPtr);

      tokenPtr = strtok(NULL, " (),to");
      strcpy(atom2, tokenPtr);
      tokenPtr = strtok(NULL, " (),to");
      strcat(atom2, tokenPtr);

      if (num_same != 0) {
	if (strcmp(atom1, last_atom1) != 0 || 
	    strcmp(atom2, last_atom2) != 0) {
	  fprintf(outPtr, 
		  "Restraint_N(%d, \"%s\", \"%s\", rest%04d, %f, %f)\n",
		  num_same, last_atom1, last_atom2, num_restraints, 
		  last_dist, last_tol);
	  num_restraints++;
	  num_same = 1;
	  strcpy(last_atom1, atom1);
	  strcpy(last_atom2, atom2);
	  last_dist = dist; last_tol = tol;
	} else {
	  num_same++;
	  last_dist = dist; last_tol = tol;
	}
      } else {
	num_same = 1;
	strcpy(last_atom1, atom1);
	strcpy(last_atom2, atom2);
	last_dist = dist; last_tol = tol;
      }
    } else {
      if (num_same != 0) {
	fprintf(outPtr, 
		"Restraint_N(%d, \"%s\", \"%s\", rest%04d, %f, %f)\n",
		num_same, last_atom1, last_atom2, num_restraints, 
		last_dist, last_tol);
	num_restraints++;
	num_same = 0;
      }
    }
  }
}

