/*******************************************************************************
*
* McXtrace, X-ray tracing package
*         Copyright 1997-2002, All rights reserved
*         Risoe National Laboratory, Roskilde, Denmark
*         Institut Laue Langevin, Grenoble, France
*
* Component: Slit
*
* %I
* Written by: Erik Knudsen
* Date: June 16, 2009
* Origin: DTU Physics
*
* Rectangular/circular slit
*
* %Description
* Based on Slit-comp by Kim Lefmann and Henrik Roennow
* A simple rectangular or circular slit. You may either
* specify the radius (circular shape), which takes precedence,
* or rectangular bounds.
* No transmission around the slit is allowed.
*
* 
*
* Example: Slit(xmin=-0.01, xmax=0.01, ymin=-0.01, ymax=0.01)
*          Slit(radius=0.01)
*
* %Parameters
* INPUT PARAMETERS:
*
* radius: [m] Radius of slit in the z=0 plane, centered at Origin.
* xmin: [m]   Lower x bound.
* xmax: [m]   Upper x bound.
* ymin: [m]   Lower y bound.
* ymax: [m]   Upper y bound.
* xwidth: [m] Width of slit. Overrides xmin,xmax.
* yheight:[m] Height of slit. Overrides ymin,ymax.
*
* Optional parameters:
* focus_xw: [m] Width of resampling window.
* focus_yh: [m] Height of resampling window.
* focus_x0: [m] Centre (x) of resampling window.
* focus_y0: [m] Centre (y) of resampling window.
* dist:     [m] Distance from slit plane to plane containing resampling target.
* %End
*******************************************************************************/


DEFINE COMPONENT Slit
DEFINITION PARAMETERS ()
SETTING PARAMETERS (xmin=0, xmax=0, ymin=0, ymax=0, radius=0, xwidth=0.001, yheight=0.001,
	dist=0,focus_xw=0, focus_yh=0, focus_x0=0, focus_y0=0)
OUTPUT PARAMETERS ()
/* X-ray parameters: (x,y,z,kx,ky,kz,phi,t,Ex,Ey,Ez,p) */


INITIALIZE
%{
  if (xwidth > 0)  {
    if (!xmin && !xmax) {
      xmax=xwidth/2;  xmin=-xmax;
    } else {
      fprintf(stderr,"Slit: %s: Error: please specify EITHER xmin & xmax or xwidth\n", NAME_CURRENT_COMP); exit(-1);
    }
  }
  if (yheight > 0) {
    if (!ymin && !ymax) {
      ymax=yheight/2; ymin=-ymax;
    } else {
      fprintf(stderr,"Slit: %s: Error: please specify EITHER ymin & ymax or ywidth\n", NAME_CURRENT_COMP); exit(-1);
    }
  }
  if (xmin == 0 && xmax == 0 && ymin == 0 && ymax == 0 && radius == 0)
  { fprintf(stderr,"Slit: %s: Warning: Running with CLOSED slit - is this intentional?? \n", NAME_CURRENT_COMP); }

  if ( (focus_xw || focus_yh) && !( (focus_xw && dist) || (focus_yh && dist) ) ){
    fprintf(stderr,"Error (%s): Inconsistent target definition\n",NAME_CURRENT_COMP);
    exit(-1);
  }
%}

TRACE
%{
  PROP_Z0;
  if (((radius == 0) && (x<xmin || x>xmax || y<ymin || y>ymax))
      || ((radius != 0) && (x*x + y*y > radius*radius))){
    ABSORB;
  }else{
    SCATTER;
  }

  if ( focus_xw || focus_yh ){
    double posx,posy,posz,pdir,k;
    coords_get(POS_A_CURRENT_COMP,&posx,&posy,&posz);

    /*we have a target behind the slit - so we now consider the ray a Huygens wavelet.*/
    double xf,yf,zf;
    randvec_target_rect_real(&xf, &yf, &zf, &pdir,
        focus_x0-posx,focus_y0-posy,dist, focus_xw, focus_yh, ROT_A_CURRENT_COMP, x, y, z, 0);
    //p*=pdir;
    k=sqrt(scalar_prod(kx,ky,kz,kx,ky,kz));
    kx=(xf-x); ky=(yf-y); kz=(zf-z);
    NORM(kx,ky,kz);
    kx*=k;ky*=k;kz*=k;
  }
%}

MCDISPLAY
%{
  
  if (radius == 0) {
    double xw, yh;
    xw = (xmax - xmin)/2.0;
    yh = (ymax - ymin)/2.0;
    multiline(3, xmin-xw, (double)ymax, 0.0,
              (double)xmin, (double)ymax, 0.0,
              (double)xmin, ymax+yh, 0.0);
    multiline(3, xmax+xw, (double)ymax, 0.0,
              (double)xmax, (double)ymax, 0.0,
              (double)xmax, ymax+yh, 0.0);
    multiline(3, xmin-xw, (double)ymin, 0.0,
              (double)xmin, (double)ymin, 0.0,
              (double)xmin, ymin-yh, 0.0);
    multiline(3, xmax+xw, (double)ymin, 0.0,
              (double)xmax, (double)ymin, 0.0,
              (double)xmax, ymin-yh, 0.0);
  } else {
    circle("xy",0,0,0,radius);
  }
%}

END
