/* setrootimage.cc - sets the root image with a nice diagonal gradient.
 *
 * Typical usage:
 *	setrootimage -width 10 -height 10 -horizontal -gradient -raised -bevel2 -from 607080 -to a0b0c0
 *
 * Command Line args:
 *
 *       options are: -display <display>
 *		      -width <width>,
 *		      -height <height>,
 *		      -flat, -solid,
 *		      -gradient, -horizontal, -vertical, -diagonal,
 *		      -crossdiagonal, -rectangle, -pyramid, -pipecross,
 *		      -elliptic, -hyperbolic,
 *		      -sunken, -raised, -bevel1, -bevel2
 *		      -from <color>, -to <color>,
 *		      -color <color> (used with solid colors)
 *
 * Issues: the styles have to be specified in a certain order follow the options
 * 	   in order from the list above. For whatever reason the Blackbox image
 *	   code barfs when its style options are not set in a certain order and
 *	   then it doesn't produce a pixmap.
 *
 * If no width and height are given on the command line then it defaults to
 * the width and size of the screen.
 *
 * Author - Frank Hale
 * Email - frankhale@yahoo.com
 * Date - 9 October 2001
 *
 * Released under the GNU GPL license
 * www.gnu.org
 */
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include "image.hh"

using namespace std;

BColor parseCommandlineColor(char* the_color)
{
	BColor color;
	
	char temp_red[3] = "/0"; 
	char temp_green[3]= "/0"; 
	char temp_blue[3]= "/0"; 
	
	for (int i=0; i<6; i++)
	{
		temp_red[0] = the_color[i++];
		temp_red[1] = the_color[i++];
		temp_green[0] = the_color[i++];
		temp_green[1] = the_color[i++];
		temp_blue[0] = the_color[i++];
		temp_blue[1] = the_color[i];
	}

	color.red = strtol(temp_red,0,16);
	color.green = strtol(temp_green,0,16);
	color.blue = strtol(temp_blue,0,16);
	
	return color;
}

// The next to macros are from aewm
// Thanks to Decklin Foster for this code!!!
#define OPT_STR(name, variable)                                      \
    if (strcmp(argv[i], name) == 0 && i+1<argc) {                    \
        variable = argv[++i];                                        \
	continue;                                                    \
    }
#define OPT_INT(name, variable)                                      \
    if (strcmp(argv[i], name) == 0 && i+1<argc) {                    \
        variable = atoi(argv[++i]);                                  \
        continue;                                                    \
    }

int main (int argc, char * argv[])
{
	Display *dpy;
	Window root;
	int screen, depth;
	Visual *visual;
	BImageControl *image_control;
	Pixmap root_pix = None;
	BColor to, from;
	
	char* opt_color="no color";
	char* opt_from="708090";
	char* opt_to="ffffff"; 
	char* opt_display="";

	int width=0;
	int height=0;

	// Default color theme style
	unsigned long style=0;
	
   	int i;	
   	
	for (i = 1; i < argc; i++) {
		OPT_STR("-from", opt_from)
		OPT_STR("-to", opt_to)
		OPT_STR("-display", opt_display)
        	
		OPT_STR("-color", opt_color)
		
		OPT_INT("-width", width);
		OPT_INT("-height", height);
		
		if (strcmp(argv[i], "-flat") == 0) 
		{
			style |= BImage_Flat;
		}

		if (strcmp(argv[i], "-sunken") == 0) 
		{
			style |= BImage_Sunken;
		}
		
		if (strcmp(argv[i], "-raised") == 0) 
		{
			style |= BImage_Raised;
		}

		if (strcmp(argv[i], "-solid") == 0) 
		{
			style |= BImage_Solid;
		}

		if (strcmp(argv[i], "-gradient") == 0) 
		{
			style |= BImage_Gradient;
		}

		if (strcmp(argv[i], "-horizontal") == 0) 
		{
			style |= BImage_Horizontal;
		}

		if (strcmp(argv[i], "-vertical") == 0) 
		{
			style |= BImage_Vertical;
		}

		if (strcmp(argv[i], "-diagonal") == 0) 
		{
			style |= BImage_Diagonal;
		}

		if (strcmp(argv[i], "-crossdiagonal") == 0) 
		{
			style |= BImage_CrossDiagonal;
		}

		if (strcmp(argv[i], "-rectangle") == 0) 
		{
			style |= BImage_Rectangle;
		}

		if (strcmp(argv[i], "-pyramid") == 0) 
		{
			style |= BImage_Pyramid;
		}

		if (strcmp(argv[i], "-pipecross") == 0) 
		{
			style |= BImage_PipeCross;
		}

		if (strcmp(argv[i], "-elliptic") == 0) 
		{
			style |= BImage_Elliptic;
		}

		if (strcmp(argv[i], "-hyperbolic") == 0) 
		{
			style |= BImage_Hyperbolic;
		}

		if (strcmp(argv[i], "-bevel1") == 0) 
		{
			style |= BImage_Bevel1;
		}

		if (strcmp(argv[i], "-bevel2") == 0) 
		{
			style |= BImage_Bevel2;
		}
		
		if(strcmp(argv[i], "-help") == 0)
		{
	        	cerr << "usage: setrootimage [options]		" << endl;
        		cerr << "   options are: -display <display>,	" << endl;
			cerr << "		-width <width>, 	" << endl;
			cerr << "		-height <height>	" << endl;
			cerr << "		-flat, -solid,		" << endl;
			cerr << "		-gradient, -horizontal, -vertical, -diagonal," << endl;
			cerr << "		-crossdiagonal, rectangle, pyramid, pipecross," << endl;
  			cerr << "		-elliptic, hyperbolic," << endl;
  			cerr << "		-sunken, -raised, -bevel1, -bevel2" << endl;
  			cerr << "		-from <color>, -to <color>" << endl;
			cerr << "		-color <color> (used with solid colors)" << endl << endl;
  			
  			cerr << "example:" << endl;
  			cerr << "	setrootimage -width 10 -height 10 -horizontal -gradient -raised -bevel2 -from 607080 -to a0b0c0" << endl;						

			exit(-1);
		}
    	}

	if(opt_display)
		dpy = XOpenDisplay (opt_display);
	else
		dpy = XOpenDisplay (NULL);

	if(!dpy)
	{
		cerr << "couldn't open display" << endl;
		exit(-1);
	}
	
	screen = DefaultScreen(dpy);
	depth = DefaultDepth(dpy, screen);
	visual = DefaultVisual(dpy, screen);
	root = RootWindow(dpy, screen);

	// Nice shade of gray
	from.red=0x70;
	from.green=0x80;
	from.blue=0x90;

	// Another nice shade of gray
	to.red=0xff;
	to.green=0xff;
	to.blue=0xff;

	if(strcmp(opt_color, "no color") != 0) 
	{
		from = parseCommandlineColor(opt_color);
		to = parseCommandlineColor(opt_color);
	} else {
		from = parseCommandlineColor(opt_from);
		to = parseCommandlineColor(opt_to);
	}

	image_control = new BImageControl(dpy, depth, root, screen, visual); 

	if(style==0) 
		style = BImage_Gradient | BImage_Diagonal;

	if( (width == 0) || (height==0) )
	{
		width =	WidthOfScreen(ScreenOfDisplay(dpy, screen));
		height = HeightOfScreen(ScreenOfDisplay(dpy, screen));
	}

	root_pix = image_control->renderImage(
			width,
			height,
			style, 
		       	from, 
		      	to);

	XSetWindowBackgroundPixmap(dpy, root, root_pix);
	XClearWindow(dpy, root);
	
	image_control->removeImage(root_pix);
	delete image_control;
		
	XCloseDisplay(dpy);

	return 0;
}
