#define _LARGEFILE_SOURCE
#define _FILE_OFFSET_BITS 64
#define GTK_DISABLE_DEPRECATED 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <unistd.h>

#include <sys/stat.h>
#include <sys/wait.h>

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

#include "include/macros.h"
#include "include/misc.h"
#include "include/callbacks.h"
#include "include/ui.h"

GtkWidget *mainwin;//main window
GtkStatusIcon* trayicon;//tray icon
GtkWidget *convert;//convert button
GtkWidget *stop;//stop button
GtkWidget *pause_continue;//pause and continue button
GtkWidget *output_path;//output path's entry
GtkWidget *list;//main list
GtkListStore *store;//list store
GtkWidget *v_format_combo;//video format combo
GtkWidget *v_codec_combo;//video codec combo
GtkWidget *a_codec_combo;//audio codec combo
GtkWidget *v_bitrate_spin;//video bitrate spin
GtkWidget *v_bitrate_auto;
GtkWidget *v_width_spin;//video width spin
GtkWidget *v_height_spin;//video height spin
GtkWidget *v_width_height_check;//checkbox
GtkWidget *v_aspect_combo;//video  aspect ratio
GtkWidget *v_fps_combo;//video frame rate
GtkWidget *a_bitrate_spin;
GtkWidget *a_bitrate_auto;
GtkWidget *a_sr_combo;//audio sampling rate
GtkWidget *a_channel_combo;//audio channels
GtkWidget *threads_combo;//number of threads
GtkWidget *subtitle_combo;//subtitle codec
GtkWidget *progress_bar;//progress bar
GtkWidget *in_file_info;//file information
GtkWidget *deinterlace_checkbox;
GtkWidget *notebook;
GtkWidget *v_gop_spin;
GtkWidget *v_gop_auto;

enum {
  COLUMN_NAME,
  COLUMN_STATUS,
  COLUMN_PATH,
  N_COLUMNS
};

struct stats {
float time;
unsigned int total_hours;
unsigned int total_minutes;
float total_seconds;
double total_time;
} stats;

struct states {
GPid pid;//process pid of encoder
gboolean paused;//paused or not paused transcoding
gboolean stoped;//stoped or not stoped transcoding
char last_input_folder[100];
char last_output_folder[100];
unsigned short notebook_tab;
char ffmpeg_path[25];
unsigned short windows_is_visible;
} states;

//--------------setting up codecs(start)----------------//
typedef struct vformat{
char* format_name;
char* combo_name;
char* extension;
}vformat;

typedef struct vcodec{
char* codec_name;
char* combo_name;
}vcodec;

typedef struct acodec{
char* codec_name;
char* combo_name;
}acodec;

vformat vformats[C_NUM_FORMATS];
vcodec  vcodecs[C_NUM_V_CODECS];
acodec  acodecs[C_NUM_A_CODECS];

void setup_settings(void)
{
	short counter;
	
	//------//
	counter=0;
	
	vformats[counter].combo_name="Ogg";
	vformats[counter].format_name="ogg";
	vformats[counter].extension=".ogg";
	counter++;
	
	vformats[counter].combo_name="Avi";
	vformats[counter].format_name="avi";
	vformats[counter].extension=".avi";
	counter++;
	
	vformats[counter].combo_name="Mp4";
	vformats[counter].format_name="mp4";
	vformats[counter].extension=".mp4";
	counter++;
	
	vformats[counter].combo_name="Webm";
	vformats[counter].format_name="webm";
	vformats[counter].extension=".webm";
	counter++;
	
	vformats[counter].combo_name="Flv";
	vformats[counter].format_name="flv";
	vformats[counter].extension=".flv";
	counter++;
	
	vformats[counter].combo_name="Mpeg";
	vformats[counter].format_name="dvd";
	vformats[counter].extension=".mpg";
	counter++;
	
	vformats[counter].combo_name="Mkv";
	vformats[counter].format_name="matroska";
	vformats[counter].extension=".mkv";
	counter++;
	
	vformats[counter].combo_name="3gp";
	vformats[counter].format_name="3gp";
	vformats[counter].extension=".3gp";
	counter++;
	
	//------//
	counter=0;
	
	vcodecs[counter].codec_name="libtheora";
	vcodecs[counter].combo_name="Theora";
	counter++;
	
	vcodecs[counter].codec_name="copy";
	vcodecs[counter].combo_name="Stream copy";
	counter++;
	
	vcodecs[counter].codec_name="libx264";
	vcodecs[counter].combo_name="H.264";
	counter++;
	
	vcodecs[counter].codec_name="libvpx";
	vcodecs[counter].combo_name="Vp8";
	counter++;
	
	vcodecs[counter].codec_name="libxvid";
	vcodecs[counter].combo_name="Xvid";
	counter++;
	
	vcodecs[counter].codec_name="flv";
	vcodecs[counter].combo_name="Flv";
	counter++;
	
	vcodecs[counter].codec_name="mpeg1video";
	vcodecs[counter].combo_name="Mpeg1";
	counter++;
	
	vcodecs[counter].codec_name="mpeg2video";
	vcodecs[counter].combo_name="Mpeg2";
	counter++;
	
	vcodecs[counter].codec_name="h263";
	vcodecs[counter].combo_name="H.263";
	counter++;
	
	//------//
	counter=0;
	
	acodecs[counter].codec_name="libvorbis";
	acodecs[counter].combo_name="Vorbis";
	counter++;
	
	acodecs[counter].codec_name="copy";
	acodecs[counter].combo_name="Stream copy";
	counter++;
	
	acodecs[counter].codec_name="aac";
	acodecs[counter].combo_name="Aac";
	counter++;
	
	acodecs[counter].codec_name="ac3";
	acodecs[counter].combo_name="Ac3";
	counter++;
	
	acodecs[counter].codec_name="libmp3lame";
	acodecs[counter].combo_name="Mp3";
	counter++;
	
	acodecs[counter].codec_name="mp2";
	acodecs[counter].combo_name="Mp2";
	counter++;
	
	acodecs[counter].codec_name="libopencore_amrnb";
	acodecs[counter].combo_name="AmrNB";
	counter++;
}
void setup_states(void)
{
	states.pid=0;
	states.paused=0;
	states.stoped=1;
	states.notebook_tab=0;
	
	if( g_file_test("ffmpeg",G_FILE_TEST_IS_EXECUTABLE) )
	{
		strcpy( states.ffmpeg_path , "./ffmpeg" );
	}
	else if(g_file_test("/usr/bin/ffmpeg",G_FILE_TEST_IS_EXECUTABLE))
	{
		strcpy( states.ffmpeg_path , "/usr/bin/ffmpeg" );
	}
	else if(g_file_test("/usr/local/bin/ffmpeg",G_FILE_TEST_IS_EXECUTABLE))
	{
		strcpy( states.ffmpeg_path , "/usr/local/bin/ffmpeg" );
	}
	else
	{
		printf("\n could not find ffmpeg \n\n");
		exit(2);
	}
	
	states.windows_is_visible = 1;
}
//--------------setting up codecs(end)----------------//
int main (int argc, char **argv)
{
	setup_settings();
	
	setup_states();
	
	gtk_init (&argc, &argv);
	
	init_ui();
	
	load_config();
	
	gtk_widget_show_all(mainwin);
	
	gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook),states.notebook_tab);//special case
	
	gtk_main();
	
	return 0;
}

#include "include/misc.c"
#include "include/callbacks.c"
#include "include/ui.c"
