// This function will be easier to write in newer pikes, where there
// will be a Image.ANY.decode function, but this will do for now. It
// decoded an image from a string and returns a mapping with the
// image, and optinally the alpha channel.
// 
// Currently supports most commonly used image formats, but only PNG
// and GIF supports alpha channels
//


mapping low_decode_image(string data)
{
  Image.image i, a;
  if(!data)
    return 0; 
  
  // Use the low-level decode function to get the alpha channel.
  catch
  {
    array chunks = Image.GIF._decode( data );

    // If there is more than one render chunk, the image is probably
    // an animation. Handling animations is left as an exercise for
    // the reader. :-)
    foreach(chunks, mixed chunk)
      if(arrayp(chunk) && chunk[0] == Image.GIF.RENDER )
        [i,a] = chunk[3..4];
  };

  if(!i) catch(i = Image.GIF.decode( data ));

  // The JPEG format is only available if JPEG library was installed
  // when pike was compiled, thus we have to conditionally compile
  // this part of the code.
#if constant(Image.JPEG) && constant(Image.JPEG.decode)
  if(!i) catch(i = Image.JPEG.decode( data ));
#endif

#if constant(Image.PNG) && constant(Image.PNG._decode)
  if(!i) catch
  {
    mixed q = Image.PNG._decode( data );
    i = q->image;
    a = q->alpha;
  };
#endif
  if(!i) 
    catch(i = Image.PNM.decode( data ));

  if(!i) // No image could be decoded at all. 
    return 0;

  return ([
    "alpha":a,
    "img":i,
  ]);
}

// This function loads and decodes and image from disk.
// Returns Image.image objects
mapping low_load_image( string filename )
{
  string data;
  catch(data = Stdio.File( filename, "r" )->read());
  return low_decode_image(data);
}

// returns GDK image objects.
mapping load_image( string filename )
{
  if(mapping a = low_load_image( filename ) )
  return ([
    "alpha": a->alpha && GDK.Bitmap( a->alpha ),
    "img":  GDK.Pixmap( a->img ),
  ]);
}

// returns GDK image objects.
mapping decode_image( string data )
{
  if(mapping a = low_decode_image( data ) )
  return ([
    "alpha": a->alpha && GDK.Bitmap( a->alpha ),
    "img":   GDK.Pixmap( a->img ),
  ]);
}

string low_encode_image( mapping img, string fmt )
{
  if(img->alpha) return 0;
  catch {
    return Image[fmt||"PNG"]->encode( img->img );
  };
  return 0;
}

string encode_image( mapping img, string fmt )
{
}




// Some shortcut handling stuff.

mapping parse_shortcut_file( string f )
{
  mapping ss = ([]);
  Stdio.File o = Stdio.File();
  if(o->open(f, "r"))
  {
    string p,k;
    foreach(o->read()/"\n", string l)
      if(sscanf(l, "\"%s\" \"%s\"", p, k) == 2)
	ss[p] = k;
  }
  return ss;
}

void save_shortcut_file( string f, mapping ss )
{
  Stdio.File o = Stdio.File();
  if(o->open(f, "wct"))
  {
    foreach(sort(indices(ss)), string s)
      o->write( "\""+s+"\" \""+ss[s]+"\"\n" );
  }
}
