/* cqcam - Color Quickcam capture programs
 * Copyright (C) 1996-1998 by Patrick Reynolds
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */

#include <gtk/gtkbox.h>
#include <gtk/gtkfilesel.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkmain.h>
#include <gtk/gtkradiobutton.h>
#include <gtk/gtksignal.h>
#include <gtk/gtktogglebutton.h>
#include <gtk/gtkvbox.h>
#include <gtk/gtkwidget.h>

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

#include "saveas.h"
#include <imager.h>

int saveas_in_progress = 0;

static unsigned char *save_buf;
static int save_width, save_height;

static void do_save(GtkWidget *but, GtkWidget *fs);
static void do_save_ppm(char *fn);
#ifdef JPEG
static void do_save_jpeg(char *fn);
#endif
static void clean_up();

struct {
  char *name;
  int initial;
  void (*savefunc)(char *);
  GtkWidget *but;
} controls[] = {
#ifdef JPEG
  { "JPEG", 1, do_save_jpeg, 0 },
#endif
  { "PPM",  0, do_save_ppm,  0 }
};
static const int ncontrols = sizeof(controls)/sizeof(controls[0]);

void do_saveas(unsigned char *buf, int width, int height) {
  if (saveas_in_progress) return;
  saveas_in_progress = 1;
  
  save_buf = buf;
  save_width = width;
  save_height = height;
  
  GtkWidget *w = gtk_file_selection_new("Save image as");
  gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(w));
  gtk_signal_connect(GTK_OBJECT(w), "destroy",
    GTK_SIGNAL_FUNC(clean_up), 0);
  gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(w)->ok_button),
    "clicked", GTK_SIGNAL_FUNC(do_save), w);
  gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(w)->cancel_button),
    "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(w));
  int i;
  GSList *group = 0;
  GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(w)->main_vbox), hbox, TRUE,
    TRUE, 0);
  GtkWidget *label = gtk_label_new("File format:");
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 8);
  for (i=0; i<ncontrols; i++) {
    GtkWidget *button = gtk_radio_button_new_with_label(group,
      controls[i].name);
    if (controls[i].initial)
#ifdef HAVE_GTK_1_0
      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
#else
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
#endif
    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
    if (i<ncontrols-1);
      group = gtk_radio_button_group(GTK_RADIO_BUTTON(button));
    controls[i].but = button;
  }
  gtk_widget_show_all(w);
}

static void do_save(GtkWidget *, GtkWidget *fs) {
  char *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs));
  printf("saving to: %s\n", fn);
  int i;
  for (i=0; i<ncontrols; i++)
    if (GTK_TOGGLE_BUTTON(controls[i].but)->active) {
      controls[i].savefunc(fn);
      break;
    }
  gtk_widget_destroy(fs);
}

static void do_save_ppm(char *fn) {
  FILE *o;
  int len = strlen(fn);
  if (len < 4 || strcasecmp(fn+len-4, ".ppm")) {
    char *buf = (char*)malloc(sizeof(char)*(len+4+1));
    strcpy(buf, fn);
    strcpy(buf+len, ".ppm");
    o = fopen(buf, "w");
    if (!o) { perror(buf); return; }
    free(buf);
  }
  else {
    o = fopen(fn, "w");
    if (!o) { perror(fn); return; }
  }
  if (!o) { perror("fopen"); return; }
  write_ppm(o, save_buf, save_width, save_height);
  if (fclose(o) < 0) perror("fclose");
}

#ifdef JPEG
static void do_save_jpeg(char *fn) {
  FILE *o;
  int len = strlen(fn);
  if (len < 4 || strcasecmp(fn+len-4, ".jpg")) {
    char *buf = (char*)malloc(sizeof(char)*(len+4+1));
    strcpy(buf, fn);
    strcpy(buf+len, ".jpg");
    o = fopen(buf, "w");
    if (!o) { perror(buf); return; }
    free(buf);
  }
  else {
    o = fopen(fn, "w");
    if (!o) { perror(fn); return; }
  }
  write_jpeg(o, save_buf, save_width, save_height, 75);  // <- quality should not be hard-coded
  if (fclose(o) < 0) perror("fclose");
}
#endif

static void clean_up() {
  saveas_in_progress = 0;
}
