#include <X11/Intrinsic.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/X.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define sigma 5.67e-8   /*Stefan Boltzman*/
#define h 6.62618e-34  /*Planck*/
#define c 2.99798e8
#define k 1.380e-23   /*Boltzman*/
#define MAX_MAPPED_STRING_LENGTH 10


/*this program generates a graph of the wavelength distribution of black
  body radiation at various wavelengths.*/


Display *dpy;
XColor xcolour;
GC gc;
XGCValues xgcvalues;
XSetWindowAttributes xsetwattrs;
Window win;
int scrn;
XEvent report;
Cursor cursor;
char PrRadc[40];
XPoint points[1000];

void SetCol (GC gc, char *str);

int
main ()
{
  double x, T, Radc, scaley;
  int i,j, keep_going = 1, x2, y2,hotkey=0,count,bufsize=MAX_MAPPED_STRING_LENGTH;
  char PrString[10];
  XComposeStatus compose;
  char buffer[MAX_MAPPED_STRING_LENGTH];
  KeySym keysym;
  void MakGraf(double T);

  if (!(dpy = XOpenDisplay (NULL)))
    {
      fprintf (stderr, "Cannot open display.\n");
      exit (1);
    }
  printf("You can change temperature while program is running using arrow keys\n");
  printf("You can exit the program by clicking on window with the mouse\n");
  printf("Enter temperature:\n");
  scanf("%lf",&T);
 
  scrn = DefaultScreen (dpy);
  xsetwattrs.backing_store = Always;
  xsetwattrs.background_pixel = BlackPixel (dpy, scrn);
  win = XCreateSimpleWindow (dpy, RootWindow (dpy, scrn), 256, 256, 1000, 500, 0,
			     WhitePixel (dpy, scrn), BlackPixel (dpy, scrn));
  gc = XCreateGC (dpy, win, 0, NULL);
  XSetStandardProperties (dpy, win, "Radiation vs T",
			  "iconname", None, 0, 0, NULL);
  XSelectInput (dpy, win, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask);
  XMapWindow (dpy, win);
  XClearWindow (dpy, win);
  cursor = XCreateFontCursor (dpy, XC_pirate);
  XDefineCursor (dpy, win, cursor);
  MakGraf(T);
  while (keep_going)
    {
      XNextEvent (dpy, &report);
      switch (report.type)
	{

	case KeyPress:
		    count=XLookupString((XKeyEvent *)&report, buffer,bufsize,&keysym,&compose);
		    buffer[count]=0x00;
         
		    if (keysym==XK_Right)
		      {            
			XClearWindow(dpy,win);
			T+=1.;
			hotkey=1;
		      }
		    if (keysym==XK_Left)
		      {            
			XClearWindow(dpy,win);
			T-=1;
			hotkey=1;
		      }
                     if (keysym==XK_Up)
		      {            
			XClearWindow(dpy,win);
			T+=10.;
			hotkey=1;
		      }
		    if (keysym==XK_Down)
		      {            
			XClearWindow(dpy,win);
			T-=10;
			hotkey=1;
		      }
                    MakGraf(T);

	case Expose:
	  {
            if (!hotkey)
              if (report.xexpose.count !=0) break;
            hotkey=0;
            SetCol (gc,"red");
	    XDrawString(dpy,win,gc,200,20,PrRadc,strlen(PrRadc));
	    SetCol (gc, "yellow");
	    XDrawLine (dpy, win, gc, 0, 480, 1000, 480);
	    for(i=1;i<10;i++)
	      {
                XDrawLine(dpy, win,gc, i*100,480,i*100,475);
		sprintf(PrString,"%d",200*i);
		XDrawString(dpy,win,gc,i*100,490,PrString,strlen(PrString));
              }
	    SetCol (gc, "green");
	    XDrawLines (dpy, win, gc, points, 1000, CoordModeOrigin);
	    break;
	  }
	case ConfigureNotify:
	  {
	    break;
	  }
	case ButtonPress:
	  {
	    keep_going = 0;
	    break;
	  }

	default:
	  break;
	}
    }
  XCloseDisplay (dpy);
  return 0;
}


void
SetCol (GC gc, char *str)
{
  if (XParseColor (dpy, DefaultColormap (dpy, scrn), str, &xcolour))
    if (XAllocColor (dpy, DefaultColormap (dpy, scrn), &xcolour))
      xgcvalues.foreground = xcolour.pixel;
  XChangeGC (dpy, gc, GCForeground, &xgcvalues);
}


void MakGraf(double T)
{
  int i;
  double x,scaley,lambda, Radl, maxRadl,Radc; 


 Radc=sigma*T*T*T*T;
 sprintf(PrRadc,"T=%6.0lf  Radc=%le",T, Radc);

for(i=0;i<1000;i++)
    {
      x=20.0*i;
      lambda=x/10e9;
      Radl=2.0*M_PI*c*c*h/(lambda*lambda*lambda*lambda*lambda*(exp(h*c/(k*lambda*T))-1.0));
      if (Radl>maxRadl) maxRadl=Radl;
    }
  scaley=480/maxRadl;



  for (i = 0; i < 1000; i++)
    {
     
      x = 20.0*i;
      points[i].x = i;
      lambda=x/10e9;
      Radl=2.0*M_PI*c*c*h/(lambda*lambda*lambda*lambda*lambda*(exp(h*c/(k*lambda*T))-1.0));
      points[i].y  =480-scaley*Radl;
      /*   printf("%d %le \n",points[i].x,Radl);*/
    }
}
