/** -*- Mode: C++; tab-width: 4 -*-
 * vim: sw=4 ts=4:
 *
 * Gnome Apt main application class
 *
 * 	(C) 1998 Havoc Pennington <hp@pobox.com>
 * 	    2002, 2003 Filip Van Raemdonck <mechanix@debian.org>
 *
 * 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
 *
 * 	$Id$
 *
 **/

using namespace std;

#include <libgnome/gnome-config.h>

#include "app.h"
#include "drawtree.h"
#include "menus.h"
#include "pkglist.h"
#include "pkgtree.h"
#include "gnome-apt.h"

///// Declarations for non-menu callbacks

static gint delete_event_cb(GtkWidget* w, GdkEvent* event, gpointer data);

///// config load/save stuff


// Eventually the --geometry command-line argument should override
//  this stuff.

static void
load_geometry (GtkWidget* app, const gchar* override) {
#if 0
	const gchar* s;
	gchar* freeable = NULL;

	if (!override) {
/* FIXME */
		s = freeable = gnome_config_get_string ("/gnome-apt/App/geometry");
	} else {
		s = override;
	}

	if (s && !gtk_window_parse_geometry (GTK_WINDOW (app), s)) {
#endif
		gtk_window_set_default_size (GTK_WINDOW (app), 800, 600);
#if 0
	}

	g_free (freeable);
#endif
}

static void
save_geometry (GtkWidget* app) {
	gchar* s;
	gint x, y, w, h;

	if (!GTK_WIDGET_REALIZED (app))
		return; // no window on screen

	gdk_window_get_geometry (app->window, &x, &y, &w, &h, NULL);

	if ((s = g_strdup_printf ("%dx%d%+d%+d", w, h, x, y))) {
/* FIXME */
		gnome_config_set_string ("/gnome-apt/App/geometry", s);
		gnome_config_sync ();
		g_free (s);
	}
}


////////////////////

GAptApp::GAptApp()
  : app_(0)
{
  init(0);
}

GAptApp::GAptApp(const gchar* geometry)
  : app_(0)
{
  init(geometry);
}

static void
status_changed_cb (GAptObject* obj, gchar* s, GAptApp* app) {
	app->set_status (s);
}

void
GAptApp::init(const gchar* geometry)
{
  g_return_if_fail(app_ == 0);

  app_    = gnome_app_new(APPNAME, _("GNOME Apt: A Package Tool"));

  load_geometry(app_, geometry);

  // we export a progress interface but for now there's no progress
  // bar shown
  appbar_ = gnome_appbar_new(FALSE, TRUE, GNOME_PREFERENCES_NEVER);

  gnome_app_set_statusbar(GNOME_APP(app_),
                          appbar_);

	app_treeview = new DrawTree (new GAptPkgTree);
	GAptPkgTree* pkgtree = app_treeview->getModel();
	pkglist_ = new GAptPkgList (app_treeview, GNOME_APPBAR (appbar_));

  gnome_app_set_contents(GNOME_APP(app_), pkglist_->widget());

	g_signal_connect (G_OBJECT (app_), "delete_event", G_CALLBACK (delete_event_cb), this);
	g_signal_connect (G_OBJECT (app_), "key_press_event", G_CALLBACK (keypress_cb), this);
	g_signal_connect (G_OBJECT (pkgtree->gaptObject()),
	      "status_changed", G_CALLBACK (status_changed_cb), this);

  progress_ = new Progress(appbar_);

  // do this last so it reflects the final state.
  gnome_apt_create_main_menu(GNOME_APP(app_), GNOME_APPBAR(appbar_), pkglist_);

  gtk_widget_show (app_);
}

GAptApp::~GAptApp (void) {
	delete app_treeview->getModel();
	delete app_treeview;
	app_treeview = 0;
  delete pkglist_;
  pkglist_ = 0;
  delete progress_;
  progress_ = 0;
  
  if (app_ != 0)
    {
      save_geometry(app_);

      gtk_widget_destroy(app_);
    }
}

//////////////////////////////////////////////
// General callbacks

static gint 
delete_event_cb(GtkWidget* w, GdkEvent* event, gpointer data)
{
  gnome_apt_quit();
  return TRUE;      // if we don't really quit, block default action.
}

// We have to process any "accelerators" here.

gint
GAptApp::keypress_cb(GtkWidget* w, GdkEventKey* event, gpointer data)
{
  GAptApp* app = static_cast<GAptApp*>(data);

  return app->key(event);
}

gint
GAptApp::key(GdkEventKey* event)
{
	if (GTK_IS_ENTRY (GTK_WINDOW (widget())->focus_widget)) {
		ga_debug ("focus_widget is entry: %s",
		      G_OBJECT_TYPE_NAME (GTK_WINDOW (widget())->focus_widget));
		return FALSE;
	} else {
		ga_debug ("focus_widget type: %s",
		      G_OBJECT_TYPE_NAME (GTK_WINDOW (widget())->focus_widget));
	}

	if (app_treeview) {
		bool handled = app_treeview->consider_key_event (event);
          if (handled)
				g_signal_stop_emission_by_name (G_OBJECT (app_), "key_press_event");
          return handled;
	}

  return FALSE;
}

//////////////////// Progress

void 
GAptApp::Progress::Update()
{
  if (CheckChange() == false)
    return;
  
  if (MajorChange == true)
    {
      gnome_appbar_set_status(GNOME_APPBAR(appbar_), Op.c_str());
    }
  
	gnome_appbar_set_progress_percentage (GNOME_APPBAR (appbar_), Percent/100.0);
  
  // flush
  while (gtk_events_pending())
    gtk_main_iteration();
}


void 
GAptApp::Progress::Done()
{
  gnome_appbar_refresh(GNOME_APPBAR(appbar_));
	gnome_appbar_set_progress_percentage (GNOME_APPBAR (appbar_), 0.0);
}

GAptApp::Progress::Progress(GtkWidget* appbar)
  : appbar_(appbar)
{

}

GAptApp::Progress::~Progress()
{

}
