/*****************************************************************************
 * camcapt.c
 *
 * 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 program 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 program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA.
 *
 * Copyright (C) 2006 Stefan Sikora hoshy ['at'] schrauberstube.de
 * Copyright (C) 2006 Zoltan Csala zcsala ['at'] users.sourceforge.net
 *
 * Released under the terms of the GPL.
 * *NO WARRANTY*
 *****************************************************************************/
 
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>

#include "camcapt.h"

#define dir_exists(x) (access((x), R_OK) == 0)

/***** Variables for frame recording */
static char capturc_path[256] = "";
char frame_dir[256] = "";
char custom_encoder[256] = "";
char encoder_options[512] = "";
int del_frames_after_encoding = 0;
int capture_auto_on = 0;
/***** End of variables for frame recording */


/* Widgets that should be accessed globally, or in other programs */                 
GtkWidget* winSetupCapture = NULL;
GtkWidget* winEncodeCapt = NULL;
GtkWidget* fileselDirCaptures = NULL;
GtkWidget* fileselCustEnc = NULL;
GtkWidget* txtCmdOptions = NULL;
GtkTextBuffer* bufCmd = NULL;

/* Gets properties from corresponding widgets and put them into variables */
void getCaptureProperties()
{
    GtkTextIter StartIter, EndIter;
    
    snprintf( frame_dir, sizeof(frame_dir) - 1,
        gtk_file_chooser_get_current_folder( GTK_FILE_CHOOSER(fileselDirCaptures) ) );

    snprintf( custom_encoder, sizeof(custom_encoder) - 1,
        gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(fileselCustEnc) ) );
        
    bufCmd = gtk_text_view_get_buffer( GTK_TEXT_VIEW(txtCmdOptions) );
    gtk_text_buffer_get_bounds( bufCmd, &StartIter, &EndIter );
    snprintf( encoder_options, sizeof(encoder_options) - 1,
        gtk_text_buffer_get_text( bufCmd, &StartIter, &EndIter, FALSE) );
} /* getCaptureProperties */


/* read capture configuration file - taken from Hoshy, by Z.Cs. */
void read_capturc () {
	FILE *f;
	char line[256];

	snprintf(capturc_path, sizeof(capturc_path) - 1, 
			 "%s/.yahoorc/gyach/capturc", getenv("HOME"));
	
	if ((f = fopen(capturc_path, "r")) == NULL) {
		/* no config available */
		return;
	}

	while (fgets(line, sizeof(line), f)) {
		char *p, *key, *value;
		
		/* Skip empty lines */
		if ( strcmp(line, "\n") == 0 || strcmp(line, "\r\n") == 0 ) {
			continue;
		}
		
		/* strip comments */
		if ( (p = strchr(line, '#')) ) {
			continue;
		}
		if ( (key = strtok(line, "=")) && (value = strtok(NULL, "\n"))) {
			if (strcmp(key,"frame_directory")==0) 
				snprintf( frame_dir, sizeof(frame_dir) - 1, value );

			else if (strcmp(key, "custom_encoder") == 0)
			        snprintf( custom_encoder, sizeof(custom_encoder) - 1, value );

			else if (strcmp(key, "del_frames_after_encoding") == 0)
				del_frames_after_encoding = atoi(value);

			else if (strcmp(key, "encoder_options") == 0)
				snprintf( encoder_options, sizeof(encoder_options) - 1, value );

			else if (strcmp(key, "capture_auto_on") == 0)
				capture_auto_on = atoi(value);

		} else {
			fprintf(stderr, "%s", line );
			fprintf(stderr, "Problems in configuration file %s\n", capturc_path);
		}		
	}
	fclose(f);
} /* read_capturc */


/* read capture configuration file - again, taken from Hoshy, by Z.Cs. */
void write_capturc() {
	FILE *f;
	
	/* create ~/.yahoorc/gyach dir if it does not exist (it should) */
	snprintf(capturc_path, sizeof(capturc_path) - 1, "%s/.yahoorc", 
			 getenv("HOME"));
	if (!dir_exists(capturc_path))
		mkdir(capturc_path, 0700);

	snprintf(capturc_path, sizeof(capturc_path) - 1, "%s/.yahoorc/gyach", 
			 getenv("HOME"));
	if (!dir_exists(capturc_path))
		mkdir(capturc_path, 0700);

	snprintf(capturc_path, sizeof(capturc_path) - 1, 
			 "%s/.yahoorc/gyach/capturc", getenv("HOME"));

	if ((f = fopen(capturc_path, "w")) == NULL) {
		fprintf(stderr, "Problems when writing configuration to %s\n",
				capturc_path);
		return;
	}
	fprintf(f, "# Configuration file for webcam capture settings\n\n" );
	fprintf(f, "# Directory where captured frames are stored\n" );
	fprintf(f, "frame_directory=%s\n", frame_dir );
	
	fprintf(f, "# Program that encodes captured frames into movie\n" );
	fprintf(f, "custom_encoder=%s\n", custom_encoder );
	
	fprintf(f, "# Command-line options for encoder program\n" );
	fprintf(f, "encoder_options=%s\n", encoder_options );

	fprintf(f, "# 1 for automatic deleting frames after encoding, 0 if not\n" );
	fprintf(f, "del_frames_after_encoding=%d\n", del_frames_after_encoding );
	
	fprintf(f, "# 1 for automatic start recording when cam starts, 0 for not\n" );
	fprintf(f, "capture_auto_on=%d\n", capture_auto_on );
	
	fclose(f);
} /* write_capturc */


/******* Callbacks ******/


void on_buttCaptCancel_clicked (GtkButton *button, gpointer user_data)
{
    gtk_widget_destroy( winSetupCapture );
}


void on_buttCaptApply_clicked (GtkButton *button, gpointer user_data)
{
    getCaptureProperties();
    write_capturc();
}


void on_buttCaptOK_clicked( GtkButton* button, gpointer user_data)
{
    getCaptureProperties();
    write_capturc();
    gtk_widget_destroy( winSetupCapture );
}


void on_buttCaptHelp_clicked( GtkButton *button, gpointer user_data)
{
}


void on_cboxCaptured_changed(GtkComboBox* combobox, gpointer user_data)
{
}


void on_cbutDelAfterEnc_toggled (GtkToggleButton *togglebutton, gpointer user_data)
{
}


void on_buttHelpEnc_clicked (GtkButton *button, gpointer user_data)
{

}


void
on_buttDelFrames_clicked               (GtkButton       *button,
                                        gpointer         user_data)
{

}


void
on_buttEncode_clicked                  (GtkButton       *button,
                                        gpointer         user_data)
{
    
}


void
on_buttCloseEnc_clicked                (GtkButton       *button,
                                        gpointer         user_data)
{
    gtk_widget_destroy( winEncodeCapt );
}


/******* GUI Creation  *******/

void showWinSetupCapt (void)
{
  GtkWidget *vboxWinCapture;
  GtkWidget *tblWinCapture;
  GtkWidget *lblDirCaptures;
  GtkWidget *scrwinCmdOptions;
  GtkWidget *hbuttonbox2;
  GtkWidget *buttCaptCancel;
  GtkWidget *buttCaptApply;
  GtkWidget *buttCaptOK;
  GtkWidget *lblEncoder;
  GtkWidget *lblCmdOptions;
  GtkWidget *buttCaptHelp;
  GtkWidget *hseparator1;
  GtkWidget *hbuttonbox1;
  GtkTooltips *tooltips;

  tooltips = gtk_tooltips_new ();

  winSetupCapture = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_container_set_border_width (GTK_CONTAINER (winSetupCapture), 5);
  gtk_window_set_title (GTK_WINDOW (winSetupCapture), _("Webcam - Frame Capture Setup"));
  gtk_window_set_position (GTK_WINDOW (winSetupCapture), GTK_WIN_POS_CENTER_ON_PARENT);

  vboxWinCapture = gtk_vbox_new (FALSE, 5);
  gtk_container_add (GTK_CONTAINER (winSetupCapture), vboxWinCapture);

  tblWinCapture = gtk_table_new (5, 2, FALSE);
  gtk_box_pack_start (GTK_BOX (vboxWinCapture), tblWinCapture, TRUE, TRUE, 0);
  gtk_table_set_row_spacings (GTK_TABLE (tblWinCapture), 5);
  gtk_table_set_col_spacings (GTK_TABLE (tblWinCapture), 5);

  fileselDirCaptures = gtk_file_chooser_button_new (_("Select A File"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
  gtk_table_attach (GTK_TABLE (tblWinCapture), fileselDirCaptures, 1, 2, 0, 1,
                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                    (GtkAttachOptions) (GTK_FILL), 0, 0);
  g_object_set (fileselDirCaptures,
                "show-hidden", TRUE,
                NULL);

  lblDirCaptures = gtk_label_new (_("Directory:"));
  gtk_table_attach (GTK_TABLE (tblWinCapture), lblDirCaptures, 0, 1, 0, 1,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_FILL), 0, 0);
  gtk_misc_set_alignment (GTK_MISC (lblDirCaptures), 0, 0.5);

  lblEncoder = gtk_label_new (_("Encoder:"));
  gtk_table_attach (GTK_TABLE (tblWinCapture), lblEncoder, 0, 1, 1, 2,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_FILL), 0, 0);
  gtk_misc_set_alignment (GTK_MISC (lblEncoder), 0, 0.5);

  fileselCustEnc = gtk_file_chooser_button_new (_("Select A File"), GTK_FILE_CHOOSER_ACTION_OPEN);
  gtk_table_attach (GTK_TABLE (tblWinCapture), fileselCustEnc, 1, 2, 1, 2,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_FILL), 0, 0);

  lblCmdOptions = gtk_label_new (_("Command\nOptions:"));
  gtk_table_attach (GTK_TABLE (tblWinCapture), lblCmdOptions, 0, 1, 2, 3,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_misc_set_alignment (GTK_MISC (lblCmdOptions), 0, 0.5);

  scrwinCmdOptions = gtk_scrolled_window_new (NULL, NULL);
  gtk_table_attach (GTK_TABLE (tblWinCapture), scrwinCmdOptions, 1, 2, 2, 3,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_FILL), 0, 0);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrwinCmdOptions), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrwinCmdOptions), GTK_SHADOW_IN);

  txtCmdOptions = gtk_text_view_new ();
  gtk_container_add (GTK_CONTAINER (scrwinCmdOptions), txtCmdOptions);
  gtk_tooltips_set_tip (tooltips, txtCmdOptions, _("Command options required for encoder"), NULL);

  buttCaptHelp = gtk_button_new_from_stock ("gtk-help");
  gtk_table_attach (GTK_TABLE (tblWinCapture), buttCaptHelp, 0, 1, 4, 5,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);

  hbuttonbox2 = gtk_hbutton_box_new ();
  gtk_table_attach (GTK_TABLE (tblWinCapture), hbuttonbox2, 1, 2, 4, 5,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_FILL), 0, 0);
  gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox2), GTK_BUTTONBOX_END);
  gtk_box_set_spacing (GTK_BOX (hbuttonbox2), 5);

  buttCaptCancel = gtk_button_new_from_stock ("gtk-cancel");
  gtk_container_add (GTK_CONTAINER (hbuttonbox2), buttCaptCancel);
  GTK_WIDGET_SET_FLAGS (buttCaptCancel, GTK_CAN_DEFAULT);

  buttCaptApply = gtk_button_new_from_stock ("gtk-apply");
  gtk_container_add (GTK_CONTAINER (hbuttonbox2), buttCaptApply);
  GTK_WIDGET_SET_FLAGS (buttCaptApply, GTK_CAN_DEFAULT);

  buttCaptOK = gtk_button_new_from_stock ("gtk-ok");
  gtk_container_add (GTK_CONTAINER (hbuttonbox2), buttCaptOK);
  GTK_WIDGET_SET_FLAGS (buttCaptOK, GTK_CAN_DEFAULT);

  hseparator1 = gtk_hseparator_new ();
  gtk_table_attach (GTK_TABLE (tblWinCapture), hseparator1, 0, 2, 3, 4,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_FILL), 0, 5);

  hbuttonbox1 = gtk_hbutton_box_new ();
  gtk_box_pack_start (GTK_BOX (vboxWinCapture), hbuttonbox1, FALSE, TRUE, 0);
  gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox1), GTK_BUTTONBOX_END);
  gtk_box_set_spacing (GTK_BOX (hbuttonbox1), 5);
  
  g_signal_connect ((gpointer) buttCaptHelp, "clicked",
                    G_CALLBACK (on_buttCaptHelp_clicked),
                    NULL);
  g_signal_connect ((gpointer) buttCaptCancel, "clicked",
                    G_CALLBACK (on_buttCaptCancel_clicked),
                    NULL);
  g_signal_connect ((gpointer) buttCaptApply, "clicked",
                    G_CALLBACK (on_buttCaptApply_clicked),
                    NULL);
  g_signal_connect ((gpointer) buttCaptOK, "clicked",
                    G_CALLBACK (on_buttCaptOK_clicked),
                    NULL);
                    
  g_signal_connect ((gpointer) winSetupCapture, "delete_event",
                     G_CALLBACK (on_buttCaptCancel_clicked), NULL);
                  
  /* Set capture properties to corresponding widgets */
  if (strcmp( frame_dir, "") != 0) {
    gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(fileselDirCaptures), frame_dir);
  }
  if (strcmp( custom_encoder, "") != 0) {
      gtk_file_chooser_set_filename( GTK_FILE_CHOOSER(fileselCustEnc), custom_encoder);
  }
  
  bufCmd = gtk_text_view_get_buffer( GTK_TEXT_VIEW(txtCmdOptions) );
  gtk_text_buffer_set_text( bufCmd, encoder_options, strlen(encoder_options) );
  
  gtk_widget_show_all( winSetupCapture );
}


void showWinEncodeCapt (void)
{
  GtkWidget *tblWinEncodeCapt;
  GtkWidget *cboxCaptured;
  GtkWidget *lblSession;
  GtkWidget *lblProgress;
  GtkWidget *cbutDelAfterEnc;
  GtkWidget *hbuttboxEnc;
  GtkWidget *buttHelpEnc;
  GtkWidget *buttDelFrames;
  GtkWidget *alignment2;
  GtkWidget *hbox2;
  GtkWidget *image2;
  GtkWidget *label8;
  GtkWidget *buttEncode;
  GtkWidget *alignment3;
  GtkWidget *hbox3;
  GtkWidget *image3;
  GtkWidget *label9;
  GtkWidget *buttCloseEnc;


  winEncodeCapt = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_name (winEncodeCapt, "winEncodeCapt");
  gtk_container_set_border_width (GTK_CONTAINER (winEncodeCapt), 5);
  gtk_window_set_title (GTK_WINDOW (winEncodeCapt), _("Webcam - Captured Frames Encoding"));
  gtk_window_set_position (GTK_WINDOW (winEncodeCapt), GTK_WIN_POS_CENTER_ON_PARENT);

  gtk_window_set_wmclass (GTK_WINDOW (winEncodeCapt), "GyachIWebcam", "gyachiwebcam");

  tblWinEncodeCapt = gtk_table_new (4, 2, FALSE);
  gtk_container_add (GTK_CONTAINER (winEncodeCapt), tblWinEncodeCapt);
  gtk_table_set_row_spacings (GTK_TABLE (tblWinEncodeCapt), 5);
  gtk_table_set_col_spacings (GTK_TABLE (tblWinEncodeCapt), 5);

  cboxCaptured = gtk_combo_box_entry_new_text ();
  gtk_table_attach (GTK_TABLE (tblWinEncodeCapt), cboxCaptured, 1, 2, 0, 1,
                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                    (GtkAttachOptions) (GTK_FILL), 0, 0);

  lblSession = gtk_label_new (_("Session:"));
  gtk_table_attach (GTK_TABLE (tblWinEncodeCapt), lblSession, 0, 1, 0, 1,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_FILL), 0, 0);
  gtk_misc_set_alignment (GTK_MISC (lblSession), 0, 0.5);

  lblProgress = gtk_label_new ("");
  gtk_table_attach (GTK_TABLE (tblWinEncodeCapt), lblProgress, 0, 2, 2, 3,
                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
  gtk_label_set_use_markup (GTK_LABEL (lblProgress), TRUE);
  gtk_label_set_line_wrap (GTK_LABEL (lblProgress), TRUE);
  gtk_misc_set_alignment (GTK_MISC (lblProgress), 0, 0.5);

  cbutDelAfterEnc = gtk_check_button_new_with_mnemonic (_("Delete frame images after encoding"));
  gtk_table_attach (GTK_TABLE (tblWinEncodeCapt), cbutDelAfterEnc, 1, 2, 1, 2,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);

  hbuttboxEnc = gtk_hbutton_box_new ();
  gtk_table_attach (GTK_TABLE (tblWinEncodeCapt), hbuttboxEnc, 0, 2, 3, 4,
                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_box_set_spacing (GTK_BOX (hbuttboxEnc), 5);

  buttHelpEnc = gtk_button_new_from_stock ("gtk-help");
  gtk_container_add (GTK_CONTAINER (hbuttboxEnc), buttHelpEnc);
  GTK_WIDGET_SET_FLAGS (buttHelpEnc, GTK_CAN_DEFAULT);

  buttDelFrames = gtk_button_new ();
  gtk_container_add (GTK_CONTAINER (hbuttboxEnc), buttDelFrames);
  GTK_WIDGET_SET_FLAGS (buttDelFrames, GTK_CAN_DEFAULT);

  alignment2 = gtk_alignment_new (0.5, 0.5, 0, 0);
  gtk_container_add (GTK_CONTAINER (buttDelFrames), alignment2);

  hbox2 = gtk_hbox_new (FALSE, 2);
  gtk_container_add (GTK_CONTAINER (alignment2), hbox2);

  image2 = gtk_image_new_from_stock ("gtk-delete", GTK_ICON_SIZE_BUTTON);
  gtk_box_pack_start (GTK_BOX (hbox2), image2, FALSE, FALSE, 0);

  label8 = gtk_label_new_with_mnemonic (_("Delete Frames"));
  gtk_box_pack_start (GTK_BOX (hbox2), label8, FALSE, FALSE, 0);

  buttEncode = gtk_button_new ();
  gtk_container_add (GTK_CONTAINER (hbuttboxEnc), buttEncode);
  GTK_WIDGET_SET_FLAGS (buttEncode, GTK_CAN_DEFAULT);

  alignment3 = gtk_alignment_new (0.5, 0.5, 0, 0);
  gtk_container_add (GTK_CONTAINER (buttEncode), alignment3);

  hbox3 = gtk_hbox_new (FALSE, 2);
  gtk_container_add (GTK_CONTAINER (alignment3), hbox3);

  image3 = gtk_image_new_from_stock ("gtk-goto-last", GTK_ICON_SIZE_BUTTON);
  gtk_box_pack_start (GTK_BOX (hbox3), image3, FALSE, FALSE, 0);

  label9 = gtk_label_new_with_mnemonic (_("Encode"));
  gtk_box_pack_start (GTK_BOX (hbox3), label9, FALSE, FALSE, 0);

  buttCloseEnc = gtk_button_new_from_stock ("gtk-close");
  gtk_container_add (GTK_CONTAINER (hbuttboxEnc), buttCloseEnc);
  GTK_WIDGET_SET_FLAGS (buttCloseEnc, GTK_CAN_DEFAULT);

  g_signal_connect ((gpointer) cboxCaptured, "changed",
                    G_CALLBACK (on_cboxCaptured_changed),
                    NULL);
  g_signal_connect ((gpointer) cbutDelAfterEnc, "toggled",
                    G_CALLBACK (on_cbutDelAfterEnc_toggled),
                    NULL);
  g_signal_connect ((gpointer) buttHelpEnc, "clicked",
                    G_CALLBACK (on_buttHelpEnc_clicked),
                    NULL);
  g_signal_connect ((gpointer) buttDelFrames, "clicked",
                    G_CALLBACK (on_buttDelFrames_clicked),
                    NULL);
  g_signal_connect ((gpointer) buttEncode, "clicked",
                    G_CALLBACK (on_buttEncode_clicked),
                    NULL);
  g_signal_connect ((gpointer) buttCloseEnc, "clicked",
                    G_CALLBACK (on_buttCloseEnc_clicked),
                    NULL);
  g_signal_connect ((gpointer) winEncodeCapt, "delete_event",
                     G_CALLBACK (on_buttCloseEnc_clicked), NULL);
                      
  gtk_widget_show_all( winEncodeCapt );
}

