/*
 * image support test. See also iconvert program
 *
 *  T.C. Zhao  (1999.03.01)
 *  With some flashy icons, this program can be made useful
 *
 *   The GUI (fdui) is placed in image->app_data;
 */

#include "forms.h"
#include "ibrowser_gui.h"   /* from fd/ directory */
#include <stdlib.h>

static FL_IMAGE *curr_image;
Colormap map;

static void show_image_info(FL_IMAGE *im)
{
     FD_ibcanvas *fdui;
     char buf[128], wl[128];

     if(!im)
         return;

     if(im->type == FL_IMAGE_GRAY16)
         sprintf(wl,"(l=%d w=%d)",im->level, im->wwidth);
     else
         wl[0] = '\0';

     sprintf(buf,"%s(%s): (%dX%d) t=%s ot=%s dt=%s cols=%d used=%d %s",
         im->infile,im->fmt_name, im->w,im->h, 
         flimage_type_name(im->type)+9,
         flimage_type_name(im->original_type)+9,
         flimage_type_name(im->display_type)+9,
         im->map_len, im->colors, wl);
       
     fdui = im->app_data;
     fl_set_object_label(fdui->text,buf);

     if(im->comments)
     {
         fl_activate_object(fdui->comments);
         fl_set_object_lcol(fdui->comments, FL_BLACK);
     }
     else
     {
         fl_deactivate_object(fdui->comments);
         fl_set_object_lcol(fdui->comments, FL_INACTIVE_COL);
     }
}

void
show_comments(FL_OBJECT *ob, long data)
{
    if(curr_image && curr_image->comments)
        fprintf(stderr,"%s\n", curr_image->comments);
}

static int load_and_show(const char *filename, void *data)
{
    FD_ibcanvas *fdui = data;
    FL_IMAGE *image;
    int r, g, b;

    image = flimage_load(filename);

    if (image)
    {
       show_image_info(image);
       fl_get_icm_color(fdui->canvas->col1, &r, &g, &b);
       image->app_background = FL_PACK3(r,g,b);
       flimage_display(image, FL_ObjWin(fdui->canvas)); 
       show_image_info(image);
       flimage_free(curr_image);
       curr_image = image;

       /* re-adjust the window level stuff */
       if(image->type == FL_IMAGE_GRAY16)
       {
           fl_set_slider_bounds(fdui->level, 0, image->gray_maxval);
           fl_set_slider_bounds(fdui->width,0,  image->gray_maxval);
       }
    }
    else
        fprintf(stderr,"can't load %s\n",filename);
    return 0;
}

void scale_image(FL_OBJECT *ob, long data)
{
     FD_ibcanvas *fdui = ob->form->fdui;
     float xs = fl_get_slider_value(fdui->xfloat);
     float ys = fl_get_slider_value(fdui->yfloat);
     int aa = fl_get_button(fdui->anti_aliasing);

     if(!curr_image)
         return;
      
     flimage_scale(curr_image, xs*curr_image->w, ys*curr_image->h, 
                  aa ? FLIMAGE_SUBPIXEL:FLIMAGE_NOSUBPIXEL);
     flimage_display(curr_image, FL_ObjWin(fdui->canvas));
     show_image_info(curr_image);
}

void flip_image(FL_OBJECT *ob, long data)
{
     FD_ibcanvas *fdui = ob->form->fdui;

     if(!curr_image)
       return;

     flimage_flip(curr_image, data);
     flimage_display(curr_image, FL_ObjWin(fdui->canvas));
}

void rotate_image(FL_OBJECT *ob, long data)
{
     FD_ibcanvas *fdui = ob->form->fdui;
     float angle = fl_get_counter_value(fdui->angle);
     int subpix = fl_get_button(fdui->anti_aliasing);
     unsigned int fill=  0;

     if(!curr_image)
         return;
      
     curr_image->fill_color = fill;
     flimage_rotate(curr_image, (angle*10), subpix ? FLIMAGE_SUBPIXEL:0);
     flimage_display(curr_image, FL_ObjWin(fdui->canvas));
     show_image_info(curr_image);
}

void write_image(FL_OBJECT *ob, long data)
{
     FD_ibcanvas *fdui = ob->form->fdui;
     const char *f;

     if(!curr_image)
          return;
     fl_use_fselector(1);
     fl_set_fselector_placement(FL_PLACE_MOUSE);
     if(!(f =  fl_show_fselector("Save Image",  0, "*",0)))
        return;
     flimage_dump(curr_image, f, fl_get_choice_text(fdui->format));
}
     
static int expose_handle(FL_OBJECT *ob, Window win,
                         int w, int h, XEvent *xev, void *data)
{
     if(curr_image)
        flimage_display(curr_image, win);
     return 0;
}

void convolve_it(FL_OBJECT *ob, long data)
{
     FD_ibcanvas *fdui = ob->form->fdui;
     int subimage = fl_get_button(fdui->subimage);

     if(!curr_image)
         return;

     if(subimage)
     {
         curr_image->subw = curr_image->w/2;
         curr_image->subh = curr_image->h/2;
         curr_image->subx = curr_image->w/4;
         curr_image->suby = curr_image->h/4;
     }
     else
        curr_image->subw = 0;

     flimage_convolve(curr_image, (int**)data, 0, 0);
     flimage_display(curr_image, FL_ObjWin(fdui->canvas));
     show_image_info(curr_image);
}

void tint_it(FL_OBJECT *ob, long data)
{
     FD_ibcanvas *fdui = ob->form->fdui;
     int subimage = fl_get_button(fdui->subimage);

     if(!curr_image)
       return;

     if(subimage)
     {
        curr_image->subw = curr_image->w/2;
        curr_image->subh = curr_image->h/2;
        curr_image->subx = curr_image->w/4;
        curr_image->suby = curr_image->h/4;
     }
     else
        curr_image->subw = 0;

     flimage_tint(curr_image, FL_PACK(0,0,200), 0.3);
     flimage_display(curr_image, FL_ObjWin(fdui->canvas));
     show_image_info(curr_image);
}

void window_level(FL_OBJECT *ob, long data)
{
     FD_ibcanvas *fdui = ob->form->fdui;

     if(!curr_image || curr_image->type != FL_IMAGE_GRAY16)
         return;

     flimage_windowlevel(curr_image, fl_get_slider_value(fdui->level),
                        fl_get_slider_value(fdui->width));
     flimage_display(curr_image, FL_ObjWin(fdui->canvas));
     show_image_info(curr_image);
}
      

void warp_it(FL_OBJECT *ob, long data)
{
    static float m[2][2] = {{0.5,0.5},{-1,0.7}};
    static float border[2][2] = {{1,0},{0,1}};
    FD_ibcanvas *fdui = ob->form->fdui;
    int subimage = fl_get_button(fdui->subimage);
    int aa = fl_get_button(fdui->anti_aliasing);
    
    if(!curr_image)
       return ;

    curr_image->fill_color = FL_PACK(255,255,0);
#if 0
    flimage_warp(curr_image, border, curr_image->w+2, curr_image->h+2, 
       (aa ? FLIMAGE_SUBPIXEL:FLIMAGE_NOSUBPIXEL)|FLIMAGE_CENTER);
#else
    flimage_warp(curr_image, m, 0,0, aa ? FLIMAGE_SUBPIXEL:FLIMAGE_NOSUBPIXEL);
#endif
    flimage_display(curr_image, FL_ObjWin(fdui->canvas));
    show_image_info(curr_image);
}

void enhance_it(FL_OBJECT *ob, long data)
{
     FD_ibcanvas *fdui = ob->form->fdui;

     if(curr_image)
     {
        flimage_enhance(curr_image,0);
        flimage_display(curr_image, FL_ObjWin(fdui->canvas));
        show_image_info(curr_image);
     }
}

void crop_it(FL_OBJECT *ob, long data)
{
     FD_ibcanvas *fdui = ob->form->fdui;
    
     if(!curr_image)
        return;
     
     if(data == 0)
     {
         flimage_autocrop(curr_image, 0);
     }
     else
     {
         curr_image->fill_color = FL_PACK(255,255,0);
         flimage_crop(curr_image, -1, -1, -1, -1);
     }
     flimage_display(curr_image, FL_ObjWin(fdui->canvas));
     show_image_info(curr_image);
}

void convert_type(FL_OBJECT *ob, long type)
{
     FD_ibcanvas *fdui = ob->form->fdui;

     if(curr_image)
     {
         flimage_convert(curr_image, type, 0);
         flimage_display(curr_image, FL_ObjWin(fdui->canvas));
         show_image_info(curr_image);
     }
}


#if STUPID_WM
/* this shouldn't be necessary, but there are too many stupid WMs */
static int enter_handle(FL_OBJECT *ob, Window win,
                         int w, int h, XEvent *xev, void *data)
{
     if(fl_vmode != FL_DirectColor)
        XInstallColormap(fl_display, map); 
     return 0;
}

#endif

/* callbacks and freeobj handles for form ibcanvas */
void browse_file(FL_OBJECT *ob, long data)
{
     fl_use_fselector(0);
     fl_set_fselector_placement(FL_PLACE_MOUSE);
     fl_set_fselector_callback(load_and_show, ob->form->fdui);
     fl_show_fselector("Load an Image",  0, "*",0);
}

void quit_callback(FL_OBJECT *ob, long data)
{
     flimage_free(curr_image);
     exit(0);
}

static int
supported_image_filter(const char *name, int type)
{
    return (type==FT_DIR || (type==FT_FILE && flimage_is_supported(name) >0 ));
} 

static void error_report(FL_IMAGE *im, const char *s)
{
     FD_ibcanvas *fdui = im->app_data;

     if(!s)
        s=" ";
     fl_set_object_label(fdui->error,s);
}

static int status_report(FL_IMAGE *im, const char *s)
{
     FD_ibcanvas *fdui = im->app_data;
     char buf[512];

     if(im->completed >= 0 && im->completed < im->total)
        sprintf(buf,"%s %3.0f%% (%4d of %4d)", s, 
                 (im->completed*100.0)/im->total,
                 im->completed, im->h);
     else 
        strcpy(buf,s);

    fl_set_object_label(fdui->status, buf);
    XFlush(fl_display);
    return 0;
}


int main(int argc, char *argv[])
{
    FD_ibcanvas *fd_ibcanvas;
    int vmode, n;
    static FLIMAGE_SETUP setup;

    fl_set_border_width(-2);
    fl_initialize(&argc, argv, 0, 0, 0);
    fd_ibcanvas = create_form_ibcanvas();
    fl_set_object_color(fd_ibcanvas->canvas, FL_COL1, FL_COL1);

    setup.visual_cue = status_report;
    setup.error_message = error_report;
    setup.app_data = fd_ibcanvas;
    setup.delay = 70;
    flimage_setup(&setup);

    flimage_enable_png();
    flimage_enable_xwd();
    flimage_enable_bmp();
    flimage_enable_xbm();
    flimage_enable_gif();
    flimage_enable_sgi();
    flimage_enable_fits();
    flimage_enable_xpm();
    flimage_enable_tiff();
#ifdef HAVE_JPEG
    flimage_enable_jpeg();
#endif

    for (n = flimage_get_number_of_formats(); n; n--)
       fl_addto_choice(fd_ibcanvas->format,
                         (flimage_get_format_info(n))->short_name);

    fl_set_dirlist_filter(supported_image_filter);

    fl_add_canvas_handler(fd_ibcanvas->canvas,
                          Expose, expose_handle, 0);

   /* fill-in form initialization code */
    vmode = fl_get_vclass();

#if STUPID_WM
    map = fl_create_colormap(fl_state[vmode].xvinfo,30);
    fprintf(stderr,"map=0x%x\n",map);
    fl_set_canvas_colormap(fd_ibcanvas->canvas, map);
    fl_add_canvas_handler(fd_ibcanvas->canvas,
                          EnterNotify, enter_handle, 0);
#endif

   /* show the first form */
    fl_show_form(fd_ibcanvas->ibcanvas,FL_PLACE_CENTERFREE,FL_FULLBORDER,"ibcanvas");
   while (fl_do_forms())
       ;
   return 0;
}


#include "ibrowser_gui.c"
