// Exercise 3
// Write a C++ program which takes a number
// as a command line argument and creates a spacegroup
// object from it.
// Extend the program to add commands to define a unit
// cell with dimensions 30, 40, 50 Angstroms.
// Create an orthogonal coordinate with value 6.0, 7.0, 9.0
// and print all the symmetry equivalent coordinates of
// that coordinate in the given spacegroup

#include <iostream>

// Include the core clipper functions
#include <clipper/clipper.h>

// Main program
int main (int argc, char** argv)
{
  // Check command line
  if (argc != 2) {
    std::cout << "Wrong number of arguments - enter a spacegroup number\n";
    exit(1);
  }
  // There should be a single argument (spacegroup number)
  // Acquire an integer value from the string (using Clipper String)
  clipper::String str(argv[1]);
  int sgnum = str.i();
  std::cout << "Spacegroup number is " << sgnum << "\n";

  // Make a spacegroup description
  clipper::Spgr_descr spgrd(sgnum);
  // Make a spacegroup object from the description
  clipper::Spacegroup spgr(spgrd);

  // Print some names to show the program has worked
  std::cout << "Spacegroup number:\t" << spgr.spacegroup_number() << "\n";
  std::cout << "           Hall  :\t" << spgr.symbol_hall() << "\n";
  std::cout << "           H-M   :\t" << spgr.symbol_hm() << "\n";
  std::cout << "           Laue  :\t" << spgr.symbol_laue() << "\n";
  // Print symops
  for (int i = 0; i < spgr.num_symops(); i++) {
    clipper::Symop op = spgr.symop(i);
    std::cout << "\t\t" << i+1 << ":\t" << op.format() << "\n";
  }

  // Define a unit cell of 30, 40, 50 Angstroms
  // Make a cell description and use this to make a cell object
  clipper::Cell_descr celld(30.0,40.0,50.0);
  clipper::Cell cell(celld);

  // Look at the cell object to check that it worked.
  std::cout << "\n" << cell.format() << "\n";

  // Create an orthogonal coordinate with value 6.0, 7.0, 9.0
  clipper::Coord_orth co(6.0,7.0,9.0);
  std::cout << co.format() << "\n";

  // Print all the symmetry equivalent coordinates of
  // the coordinate in the given spacegroup
  // Note that symops are specialised form of RTop_frac
  // i.e. they operate in fractional coordinates
  for ( int i = 0; i < spgr.num_symops(); i++) {
    clipper::Coord_frac cf1 = co.coord_frac(cell);
    clipper::Coord_frac cf2 = spgr.symop(i) * cf1;
    clipper::Coord_orth equiv = cf2.coord_orth(cell);
    std::cout << "Equivalent " << i << ": " << equiv.format() <<"\n";
  }
  // Alternatively could convert the operators to orthogonal
  // coordinates, e.g.
  // clipper::RTop_orth = ...

  // Finish don't use exit, as this avoids the normal clearing
  // up done by C++
}
