#include <sys/types.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xcms.h> 

#define SPEED (1 * 1000)
#define DELAY 100

void drawline(Display *display, Window , GC gc, u_long fgcolor, u_long bgcolor, int xaxis, int width, int height);

int
main(void)
{
	Display *display;

	int i, j, w;
	int screen, depth;
	int status;
	int x, y, width, height;
	
	Window window, rootwindow;
	Visual *visual = CopyFromParent;
	
	XSetWindowAttributes attributes;
	Colormap colormap;
	XColor hardwarecolor, exactcolor;

	XGCValues xgcvalues;
	GC gc;
	Font font;
	
	XEvent event;

	u_long attr_mask;
	u_long black, white, red;
	u_long green, blue, magenta;

	char *message = "This is a test.  BSD costs 40 bux.  OpenBSD 4.7, FreeBSD 8.0, NetBSD 5.x...  Also you'll see that Linux is less value!!!";
	char *pm = message;

	/* connect to server */
	display = XOpenDisplay(NULL);
	
	if (display == NULL) {
		fprintf(stderr, "cannot connect to X server\n");
		exit(1);
	}	

	screen = DefaultScreen(display);
	rootwindow = RootWindow(display, screen);

	/* set up visual */	
	
	if (DefaultVisual(display, screen)->class == TrueColor) {
		visual = DefaultVisual(display, screen);
		depth = DefaultDepth(display, screen);
	}

	/* Open a window */
		
	x = 0;
	y = 0;

	width = DisplayWidth(display, screen);
	height = DisplayHeight(display, screen);

	attributes.event_mask = ExposureMask |  KeyPressMask | KeyReleaseMask;
	attributes.border_pixel = WhitePixel(display, screen);
	attributes.background_pixel = BlackPixel(display, screen);

#if 0
	attributes.override_redirect = True;
	attr_mask = CWOverrideRedirect | CWEventMask | CWBackPixel | CWBorderPixel;
#endif
	attr_mask = CWEventMask | CWBackPixel | CWBorderPixel;


	window = XCreateWindow(display, rootwindow, x, y, width, height,
		1, CopyFromParent, InputOutput, visual, attr_mask, 
		&attributes);

	if (window == NULL) {
		fprintf(stderr, "could not open window\n");
		exit(1);
	}

	/* set up colors */
	
	if (visual == DefaultVisual(display, screen)) {
		colormap = DefaultColormap(display, screen);
	}

	if (XAllocNamedColor(display, colormap, "black", &hardwarecolor,
		&exactcolor) != 0) {
		black = hardwarecolor.pixel;
	} else {
		black = WhitePixel(display, screen);
	}

	if (XAllocNamedColor(display, colormap, "white", &hardwarecolor,
		&exactcolor) != 0) {
		white = hardwarecolor.pixel;
	} else {
		white = WhitePixel(display, screen);
	}
	
	if (XAllocNamedColor(display, colormap, "red", &hardwarecolor,
		&exactcolor) != 0) {
		red = hardwarecolor.pixel;
	} else {
		red = WhitePixel(display, screen);
	}
	
	
	if (XAllocNamedColor(display, colormap, "blue", &hardwarecolor,
		&exactcolor) != 0) {
		blue = hardwarecolor.pixel;
	} else {
		blue = WhitePixel(display, screen);
	}

	if (XAllocNamedColor(display, colormap, "green", &hardwarecolor,
		&exactcolor) != 0) {
		green = hardwarecolor.pixel;
	} else {
		green = WhitePixel(display, screen);
	}

	if (XAllocNamedColor(display, colormap, "magenta", &hardwarecolor,
		&exactcolor) != 0) {
		magenta = hardwarecolor.pixel;
	} else {
		magenta = WhitePixel(display, screen);
	}

	/* setup gc */
	
	gc = XCreateGC(display, window, ( GCForeground | GCBackground), 
		(XGCValues *)&xgcvalues);

	/* set up fonts */
	
	font = XLoadFont(display, "-adobe-helvetica-bold-r-normal--34-240-100-100-p-182-iso10646-1");
	XSetFont(display, gc, font);
	
	/* start the window */

	XMapRaised(display, window);
	XFlush(display);

	XSetBackground(display, gc, black);
	j = width;

	for (w = 0;; w++) {
	
	for (i = 35; i < height; i++) {

		if (i % DELAY == 0)  {
			XSetForeground(display, gc, black);
			XFillRectangle(display, window, gc, 0, 0, width, 35);

			XSetForeground(display, gc, white);
			XDrawImageString(display, window, gc, j, 34, message, strlen(message));
			j -= 10;
			if (j < 0) {
				j = 0;
				message++;
				if (*message == '\0') {
					message = pm;
					j = DisplayWidth(display, screen);
				}
			}
	
			XFlush(display);
		}
	
		drawline(display, window, gc, magenta, black, i, width, height);



	}
	
	for (i = height; i > 35; i--) {
		if (i % DELAY == 0)  {
			XSetForeground(display, gc, black);
			XFillRectangle(display, window, gc, 0, 0, width, 35);

			XSetForeground(display, gc, white);
			XDrawImageString(display, window, gc, j, 34, message, strlen(message));
			j -= 10;

			if (j <= 0) {
				j = 0;
				message++;
				if (*message == '\0') {
					message = pm;
					j = DisplayWidth(display, screen);
				}
			}
		}

		drawline(display, window, gc, magenta, black, i, width, height);

	}

#if 0
	XNextEvent(display, &event);

	switch (event.type) {
	case KeyPress:
		break;
	}
#endif

	if (XCheckTypedEvent(display, KeyPress , &event) == True)
		goto out;

	} /* w */

out:
	return 0;
}

void
drawline(Display *display, Window window, GC gc, u_long fgcolor, u_long bgcolor, int xaxis, int width, int height)
{
		int median;
		int percentage;

		median = height / 4;
		percentage = xaxis / median;

		XSetForeground(display, gc, fgcolor);

		XDrawLine(display, window, gc, 0, xaxis - (1 * percentage), width / 2, xaxis);
		XDrawLine(display, window, gc, width / 2, xaxis, width, xaxis - (1 * percentage));

		XDrawLine(display, window, gc, 0, xaxis - (20 * percentage), width / 2, xaxis);
		XDrawLine(display, window, gc, width / 2, xaxis, width, xaxis - (20 * percentage));

		XDrawLine(display, window, gc, 0, xaxis - (40 * percentage), width / 2, xaxis);
		XDrawLine(display, window, gc, width / 2, xaxis, width, xaxis - (40 * percentage));


		XFlush(display);

		usleep(SPEED);

		XSetForeground(display, gc, bgcolor);
		XDrawLine(display, window, gc, 0, xaxis - (1 * percentage), width / 2, xaxis);
		XDrawLine(display, window, gc, width / 2, xaxis, width, xaxis - (1 * percentage));

		XDrawLine(display, window, gc, 0, xaxis - (20 * percentage), width / 2, xaxis);
		XDrawLine(display, window, gc, width / 2, xaxis, width, xaxis - (20 * percentage));

		XDrawLine(display, window, gc, 0, xaxis - (40 * percentage), width / 2, xaxis);
		XDrawLine(display, window, gc, width / 2, xaxis, width, xaxis - (40 * percentage));
		XFlush(display);
}

