#!/usr/local/bin/pike

// This is -*- pike -*- code.

// Set the background of the root window. This program supports
// virtual roots, unlike the 'normal' xsetroot program.

// Also supports a few extra arguments (mostly useful as demos, not
// really all that useful. :-)

constant help_text=
#"%s:
 -wid <id>: Set the background of the window with id id.
 -fg, -bg, rv, -mod, -gray, -grey and -solid: As the normal xsetroot

 -scale color1:color2:color3:color4   
     create a nice crossfade on the background. 
     Somewhat CPU intesive, and memory wasting. :-)
 -test
     create a nice test image and use it as the background.
 -grad [curvesteepness(float)] x:y:color x:y:color ...
     test it to see what it does..
  -image <image-file>
     tile image over the background
  -max <image-file>
     scale image so that it fills the whole background
";


int main(int q, array a) 
{
  if(sizeof(a)>1)
  {
    GTK.setup_gtk();

    object i;

    GDK.Window root = GTK.root_window();
    array maybe=root->children()->get_property(GDK.Atom.__SWM_VROOT)-({0});
    if(sizeof(maybe)) root=GDK.Window( maybe[0]->data[0] );

    array fg = ({ 0,0,0 });
    array bg = ({ 255,255,255 });
    int j;
    while(++j<q)
    {
      switch(a[j])
      {
       case "-help": case "--help":
         write(help_text, a[0]);
         _exit(0);
       case "-wid":  root = GDK.Window( (int)a[++j] );    break;
       case "-fg":   fg = Colors.parse_color( a[++j] );   break;
       case "-bg":   bg = Colors.parse_color( a[++j] );   break;
       case "-rv":   [fg,bg]= ({bg,fg});                  break;
       case "-mod":
         i = Image.image( (int)a[++j], (int)a[++j],@fg )->setcolor(@bg);
         i->box(1,1,i->xsize(),i->ysize());
         break;
       case "-gray": case "-grey":
         i = Image.image(2,2,@fg)->setcolor( @bg )
           ->setpixel(0,0)->setpixel(1,1);
         break;
       case "-solid":
         root->set_background(GDK.Color(@Colors.parse_color( a[++j] ))); 
         break;
       case "-scale":
         array cs = Array.map(a[++j]/":", Colors.parse_color);
         int w = root->xsize(), h = root->ysize();
         if(sizeof(cs) != 4) { werror("Please specify 4 colors\n");_exit(1); }
         if(cs[0] == cs[1] && cs[2] == cs[3]) w = 64;
         if(cs[0] == cs[2] && cs[1] == cs[3]) h = 64;
         i=Image.image( w, h )->tuned_box(0,0,w-1,h-1,cs);
         break;
       case "-test":
         i = Image.image(root->xsize(),root->ysize())->test();
         break;
       case "-grad": /* This option steals the rest of the options.. */
         float grad = 1.0;
         array points = Array.map( a[++j..], `/, ":");
         if(sizeof(points[0]) == 1)
           (grad = (float)points[0][0]), (points=points[1..]);
         points=Array.map(points,lambda(array q) {
                                   return ((array(int))q[..1]+
                                           Colors.parse_color(q[-1]));
                                 });
         i = Image.image(root->xsize(),root->ysize())->gradients(@points,grad);
         j = sizeof(a)+1;
         break;

       default: /* -image and -max */
         string d = Stdio.read_bytes( a[++j] );
         if(!d){ werror("No image to show.\n"); _exit(1); }
         foreach( ({"GIF","PNG","XWD","PNM","JPEG"}), string f )
           if(!catch(i=Image[f]->decode(d)) && i) break;
         if(a[j-1] == "-max")
           i = i->scale(root->xsize(),root->ysize());
      }
    }
    if(i)
      root->set_background(GDK.Pixmap( i ));
    root->clear();
  } else
    write(help_text, a[0]);
  _exit(0);
}
