/*******************************************************************************
*                                                                              *
*                                   Viewmol                                    *
*                                                                              *
*                               M I L L E R . C                                *
*                                                                              *
*                 Copyright (c) Joerg-R. Hill, October 2003                    *
*                                                                              *
********************************************************************************
*
* $Id: miller.c,v 1.2 2003/11/07 11:06:56 jrh Exp $
* $Log: miller.c,v $
* Revision 1.2  2003/11/07 11:06:56  jrh
* Release 2.4
*
* Revision 1.1  2000/12/10 15:11:39  jrh
* Initial revision
*
*
*/
#include<math.h>
#include<stdio.h>
#include<string.h>
#include "viewmol.h"

void millerPlane(void);

extern void fractionalToCartesian(struct ATOM *, double, double, double, double,
                                  double, double, struct MOLECULE *, int, int);
extern double bondLength(struct ATOM *, int, int);
extern double bondAngle(struct ATOM *, int, int, int);
extern void *getmem(size_t, size_t);

extern struct WINDOW windows[];
extern struct MOLECULE *molecules;
extern struct ELEMENT *elements;
extern int ne;

/* need to delete added atoms once Miller plane display has been disabled */
void millerPlane(void)
{
  struct MOLECULE *mol;
  struct ELEMENT *mp=NULL;
  double sx=0.0, sy=0.0, sz=0.0;
  int n;
  register int i, j, k;

  if (windows[VIEWER].set < 0)
    mol=&molecules[0];
  else
    mol=&molecules[windows[VIEWER].set];
  
  if (mol->unitcell)
  {
    for (i=0; i<ne; i++)
    {
      if (!strncmp(elements[i].symbol, "Mp", 2))
      {
        mp=&elements[i];
        break;
      }
    }
    if (mol->unitcell->nmiller == 0)
    {
      mol->unitcell->np=4;
      mol->unitcell->millerPlanes=(struct ATOM *)getmem((size_t)mol->unitcell->np,
                                                        sizeof(struct ATOM));
    }

    n=0;
    for (i=0; i<3; i++)
    {
      if (mol->unitcell->miller[i] != 0)
      {
        mol->unitcell->millerPlanes[n].x=0.0;
        mol->unitcell->millerPlanes[n].y=0.0;
        mol->unitcell->millerPlanes[n].z=0.0;
        mol->unitcell->millerPlanes[n].element=mp;
        switch (i)
        {
          case 0: mol->unitcell->millerPlanes[n].x=1.0/(double)(mol->unitcell->miller[i]);
                  break;
          case 1: mol->unitcell->millerPlanes[n].y=1.0/(double)(mol->unitcell->miller[i]);
                  break;
          case 2: mol->unitcell->millerPlanes[n].z=1.0/(double)(mol->unitcell->miller[i]);
                  break;
        }
        n++;
      }
    }
    for (i=0; i<3; i++)
    {
      j=n;
      if (mol->unitcell->miller[i] == 0)
      {
        for (k=n-1; k>=0; k--)
        {
          mol->unitcell->millerPlanes[j].x=mol->unitcell->millerPlanes[k].x;
          mol->unitcell->millerPlanes[j].y=mol->unitcell->millerPlanes[k].y;
          mol->unitcell->millerPlanes[j].z=mol->unitcell->millerPlanes[k].z;
          mol->unitcell->millerPlanes[j].element=mp;
          switch (i)
          {
            case 0: mol->unitcell->millerPlanes[j].x+=1.0;
                    break;
            case 1: mol->unitcell->millerPlanes[j].y+=1.0;
                    break;
            case 2: mol->unitcell->millerPlanes[j].z+=1.0;
                    break;
          }
          j++;
        }
      }
      n=j;
    }
    for (i=n-1; i>=0; i--)
    {
      if (mol->unitcell->millerPlanes[i].x < 0.0) sx=1.0;
      if (mol->unitcell->millerPlanes[i].y < 0.0) sy=1.0;
      if (mol->unitcell->millerPlanes[i].z < 0.0) sz=1.0;
    }
    for (i=n-1; i>=0; i--)
    {
      mol->unitcell->millerPlanes[i].x+=sx;
      mol->unitcell->millerPlanes[i].y+=sy;
      mol->unitcell->millerPlanes[i].z+=sz;
    }
    mol->unitcell->nmiller=n;
    fractionalToCartesian(mol->unitcell->millerPlanes, mol->unitcell->a,
                          mol->unitcell->b, mol->unitcell->c, mol->unitcell->alpha,
				  mol->unitcell->beta, mol->unitcell->gamma, NULL, 0, n);
    j=0;
    for (i=0; i<n; i++)
    {
      mol->unitcell->millerPlanes[i].x+=mol->unitcell->corners[0].x;
      mol->unitcell->millerPlanes[i].y+=mol->unitcell->corners[0].y;
      mol->unitcell->millerPlanes[i].z+=mol->unitcell->corners[0].z;
/*    printf("%f %f %f\n", mol->unitcell->millerPlanes[i].x, mol->unitcell->millerPlanes[i].y,
             mol->unitcell->millerPlanes[i].z); */
    }
  }
}
