[libgweather] API Break: correct namespacing and make WeatherInfo more GObject friendly



commit 0729a784672e2a26fe19185c01562798039eb926
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Tue Mar 22 21:51:35 2011 +0100

    API Break: correct namespacing and make WeatherInfo more GObject friendly
    
    WeatherInfo becomes GWeatherInfo, a GObject, with private data (it
    was already opaque), properties (write only for now, I plan to improve
    on that later, when I'll convert all getters) and signals. WeatherLocation
    has been removed, you can now either pass a GWeatherLocation (obtained from
    the database), or use the default from preferences. WeatherPrefs was
    removed, and GWeatherPrefs made opaque. GWeatherPrefs can be reintroduced
    when we figure out the story of locations.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=587017

 libgweather/Makefile.am         |    2 +-
 libgweather/gweather-gconf.c    |    4 +-
 libgweather/gweather-gconf.h    |    2 -
 libgweather/gweather-location.c |   37 +--
 libgweather/gweather-location.h |    3 -
 libgweather/gweather-prefs.c    |   26 +-
 libgweather/gweather-prefs.h    |   53 +--
 libgweather/gweather-xml.c      |    6 +-
 libgweather/test_metar.c        |   29 +-
 libgweather/test_sun_moon.c     |   33 +-
 libgweather/weather-bom.c       |   20 +-
 libgweather/weather-iwin.c      |  117 ++---
 libgweather/weather-met.c       |   12 +-
 libgweather/weather-metar.c     |  220 +++++----
 libgweather/weather-moon.c      |   77 ++--
 libgweather/weather-priv.h      |  151 ++++---
 libgweather/weather-sun.c       |   54 +-
 libgweather/weather-wx.c        |   43 +-
 libgweather/weather.c           | 1116 ++++++++++++++++++++++++---------------
 libgweather/weather.h           |  254 +++++-----
 20 files changed, 1270 insertions(+), 989 deletions(-)
---
diff --git a/libgweather/Makefile.am b/libgweather/Makefile.am
index 111b395..01af8c5 100644
--- a/libgweather/Makefile.am
+++ b/libgweather/Makefile.am
@@ -9,7 +9,7 @@ AM_CPPFLAGS = 			\
 AM_CFLAGS = $(WARN_CFLAGS)
 
 gweather_old_headers = \
-	weather.h gweather-gconf.h gweather-prefs.h gweather-xml.h
+	gweather-gconf.h gweather-prefs.h gweather-xml.h
 gweather_new_headers = \
 	gweather-location.h location-entry.h \
 	gweather-timezone.h timezone-menu.h
diff --git a/libgweather/gweather-gconf.c b/libgweather/gweather-gconf.c
index eca1fc3..9230002 100644
--- a/libgweather/gweather-gconf.c
+++ b/libgweather/gweather-gconf.c
@@ -193,7 +193,7 @@ gweather_gconf_get_string (GWeatherGConf  *ctx,
 
 
 WeatherLocation *
-gweather_gconf_get_location (GWeatherGConf *ctx)
+_gweather_gconf_get_location (GWeatherGConf *ctx)
 {
     WeatherLocation *location;
     gchar *name, *code, *zone, *radar, *coordinates;
@@ -302,7 +302,7 @@ gweather_gconf_get_location (GWeatherGConf *ctx)
 	    coordinates = g_strdup ("40-32N 080-13W");
     }
 
-    location = weather_location_new (name, code, zone, radar, coordinates,
+    location = _weather_location_new (name, code, zone, radar, coordinates,
 				     NULL, NULL);
 
     g_free (name);
diff --git a/libgweather/gweather-gconf.h b/libgweather/gweather-gconf.h
index 71aa29b..4f3f1a2 100644
--- a/libgweather/gweather-gconf.h
+++ b/libgweather/gweather-gconf.h
@@ -47,8 +47,6 @@ void			gweather_gconf_free		(GWeatherGConf *ctx);
 
 GConfClient *		gweather_gconf_get_client	(GWeatherGConf *ctx);
 
-WeatherLocation *	gweather_gconf_get_location	(GWeatherGConf *ctx);
-
 gchar *			gweather_gconf_get_full_key	(GWeatherGConf *ctx,
 							 const gchar *key);
 
diff --git a/libgweather/gweather-location.c b/libgweather/gweather-location.c
index 7005e71..fa76640 100644
--- a/libgweather/gweather-location.c
+++ b/libgweather/gweather-location.c
@@ -748,8 +748,7 @@ gweather_location_get_city_name (GWeatherLocation *loc)
 }
 
 WeatherLocation *
-gweather_location_to_weather_location (GWeatherLocation *gloc,
-				       const char *name)
+_weather_location_from_gweather_location (GWeatherLocation *gloc, const gchar *name)
 {
     const char *code = NULL, *zone = NULL, *radar = NULL, *tz_hint = NULL;
     GWeatherLocation *l;
@@ -758,9 +757,6 @@ gweather_location_to_weather_location (GWeatherLocation *gloc,
 
     g_return_val_if_fail (gloc != NULL, NULL);
 
-    if (!name)
-	name = gweather_location_get_name (gloc);
-
     if (gloc->level == GWEATHER_LOCATION_CITY && gloc->children)
 	l = gloc->children[0];
     else
@@ -783,33 +779,10 @@ gweather_location_to_weather_location (GWeatherLocation *gloc,
 	l = l->parent;
     }
 
-    wloc = weather_location_new (name, code, zone, radar, coords,
-				 gweather_location_get_country (gloc),
-				 tz_hint);
+    wloc = _weather_location_new (name ? name : gweather_location_get_name (gloc),
+				  code, zone, radar, coords,
+				  gweather_location_get_country (gloc),
+				  tz_hint);
     g_free (coords);
     return wloc;
 }
-
-/**
- * gweather_location_get_weather:
- * @loc: a %GWeatherLocation
- *
- * Creates a #WeatherInfo corresponding to @loc; you can use
- * weather_info_update() to fill it in.
- *
- * Return value: (transfer full): a #WeatherInfo corresponding to
- * @loc.
- **/
-WeatherInfo *
-gweather_location_get_weather (GWeatherLocation *loc)
-{
-    WeatherLocation *wloc;
-    WeatherInfo *info;
-
-    g_return_val_if_fail (loc != NULL, NULL);
-
-    wloc = gweather_location_to_weather_location (loc, NULL);
-    info = weather_info_new (wloc, NULL, NULL, NULL);
-    weather_location_free (wloc);
-    return info;
-}
diff --git a/libgweather/gweather-location.h b/libgweather/gweather-location.h
index 9d4ab47..6ef869a 100644
--- a/libgweather/gweather-location.h
+++ b/libgweather/gweather-location.h
@@ -27,7 +27,6 @@
 
 #include <glib.h>
 #include <libgweather/gweather-timezone.h>
-#include <libgweather/weather.h>
 
 G_BEGIN_DECLS
 
@@ -80,8 +79,6 @@ void                   gweather_location_free_timezones (GWeatherLocation  *loc,
 const char            *gweather_location_get_code       (GWeatherLocation  *loc);
 char                  *gweather_location_get_city_name  (GWeatherLocation  *loc);
 
-WeatherInfo           *gweather_location_get_weather    (GWeatherLocation  *loc);
-
 G_END_DECLS
 
 #endif /* __GWEATHER_LOCATIONS_H__ */
diff --git a/libgweather/gweather-prefs.c b/libgweather/gweather-prefs.c
index 1f3b5c3..b453700 100644
--- a/libgweather/gweather-prefs.c
+++ b/libgweather/gweather-prefs.c
@@ -30,12 +30,12 @@
 #include "gweather-prefs.h"
 #include "weather-priv.h"
 
-
 /**
  * SECTION:gweather-prefs
  * @Title: gweather-prefs
  */
 
+WeatherLocation *       _gweather_gconf_get_location (GWeatherGConf *ctx);
 
 static GConfEnumStringPair temp_unit_enum_map [] = {
     { TEMP_UNIT_DEFAULT,    N_("Default") },
@@ -257,25 +257,25 @@ parse_distance_string (const gchar *gconf_str, GWeatherPrefs *prefs)
 }
 
 const char *
-gweather_prefs_temp_enum_to_string (TempUnit temp)
+gweather_prefs_temp_enum_to_string (GWeatherTemperatureUnit temp)
 {
     return gconf_enum_to_string (temp_unit_enum_map, temp);
 }
 
 const char *
-gweather_prefs_speed_enum_to_string (SpeedUnit speed)
+gweather_prefs_speed_enum_to_string (GWeatherSpeedUnit speed)
 {
     return gconf_enum_to_string (speed_unit_enum_map, speed);
 }
 
 const char *
-gweather_prefs_pressure_enum_to_string (PressureUnit pressure)
+gweather_prefs_pressure_enum_to_string (GWeatherPressureUnit pressure)
 {
     return gconf_enum_to_string (pressure_unit_enum_map, pressure);
 }
 
 const char *
-gweather_prefs_distance_enum_to_string (DistanceUnit distance)
+gweather_prefs_distance_enum_to_string (GWeatherDistanceUnit distance)
 {
     return gconf_enum_to_string (distance_unit_enum_map, distance);
 }
@@ -291,9 +291,9 @@ gweather_prefs_load (GWeatherPrefs *prefs, GWeatherGConf *ctx)
     g_return_if_fail (ctx != NULL);
 
     if (prefs->location) {
-	weather_location_free (prefs->location);
+	_weather_location_free (prefs->location);
     }
-    prefs->location = gweather_gconf_get_location (ctx);
+    prefs->location = _gweather_gconf_get_location (ctx);
 
     /* Assume we use unit defaults */
     prefs->use_temperature_default = TRUE;
@@ -343,7 +343,7 @@ gweather_prefs_load (GWeatherPrefs *prefs, GWeatherGConf *ctx)
     return;
 }
 
-TempUnit
+GWeatherTemperatureUnit
 gweather_prefs_parse_temperature (const char *str, gboolean *is_default)
 {
     GWeatherPrefs prefs;
@@ -356,7 +356,7 @@ gweather_prefs_parse_temperature (const char *str, gboolean *is_default)
     return prefs.temperature_unit;
 }
 
-SpeedUnit
+GWeatherSpeedUnit
 gweather_prefs_parse_speed (const char *str, gboolean *is_default)
 {
     GWeatherPrefs prefs;
@@ -378,25 +378,25 @@ get_translated_unit (int unit, GConfEnumStringPair *pairs, int min_value, int ma
 }
 
 const char *
-gweather_prefs_get_temp_display_name (TempUnit temp)
+gweather_prefs_get_temp_display_name (GWeatherTemperatureUnit temp)
 {
     return get_translated_unit (temp, temp_unit_enum_map, TEMP_UNIT_DEFAULT, TEMP_UNIT_FAHRENHEIT);
 }
 
 const char *
-gweather_prefs_get_speed_display_name (SpeedUnit speed)
+gweather_prefs_get_speed_display_name (GWeatherSpeedUnit speed)
 {
     return get_translated_unit (speed, speed_unit_enum_map, SPEED_UNIT_DEFAULT, SPEED_UNIT_BFT);
 }
 
 const char *
-gweather_prefs_get_pressure_display_name (PressureUnit pressure)
+gweather_prefs_get_pressure_display_name (GWeatherPressureUnit pressure)
 {
     return get_translated_unit (pressure, pressure_unit_enum_map, PRESSURE_UNIT_DEFAULT, PRESSURE_UNIT_ATM);
 }
 
 const char *
-gweather_prefs_get_distance_display_name (DistanceUnit distance)
+gweather_prefs_get_distance_display_name (GWeatherDistanceUnit distance)
 {
     return get_translated_unit (distance, distance_unit_enum_map, DISTANCE_UNIT_DEFAULT, DISTANCE_UNIT_MILES);
 }
diff --git a/libgweather/gweather-prefs.h b/libgweather/gweather-prefs.h
index 94fb78a..430c966 100644
--- a/libgweather/gweather-prefs.h
+++ b/libgweather/gweather-prefs.h
@@ -36,41 +36,22 @@
 
 typedef struct _GWeatherPrefs GWeatherPrefs;
 
-struct _GWeatherPrefs {
-    WeatherLocation *location;
-    gint update_interval;  /* in seconds */
-    gboolean update_enabled;
-    gboolean detailed;
-    gboolean radar_enabled;
-    gboolean use_custom_radar_url;
-    gchar *radar;
-
-    TempUnit     temperature_unit;
-    gboolean     use_temperature_default;
-    SpeedUnit    speed_unit;
-    gboolean     use_speed_default;
-    PressureUnit pressure_unit;
-    gboolean     use_pressure_default;
-    DistanceUnit distance_unit;
-    gboolean     use_distance_default;
-};
-
-void		gweather_prefs_load			(GWeatherPrefs *prefs,
-							 GWeatherGConf *ctx);
-
-const char *	gweather_prefs_temp_enum_to_string	(TempUnit temp);
-const char *	gweather_prefs_speed_enum_to_string	(SpeedUnit speed);
-const char *	gweather_prefs_pressure_enum_to_string	(PressureUnit pressure);
-const char *	gweather_prefs_distance_enum_to_string	(DistanceUnit distance);
-
-TempUnit        gweather_prefs_parse_temperature        (const char *str,
-                                                         gboolean   *is_default);
-SpeedUnit       gweather_prefs_parse_speed              (const char *str,
-                                                         gboolean   *is_default);
-
-const char *	gweather_prefs_get_temp_display_name		(TempUnit temp);
-const char *	gweather_prefs_get_speed_display_name		(SpeedUnit speed);
-const char *	gweather_prefs_get_pressure_display_name	(PressureUnit pressure);
-const char *	gweather_prefs_get_distance_display_name	(DistanceUnit distance);
+void	                gweather_prefs_load			(GWeatherPrefs *prefs,
+								 GWeatherGConf *ctx);
+
+const char *            gweather_prefs_temp_enum_to_string	(GWeatherTemperatureUnit temp);
+const char *            gweather_prefs_speed_enum_to_string	(GWeatherSpeedUnit speed);
+const char *            gweather_prefs_pressure_enum_to_string	(GWeatherPressureUnit pressure);
+const char *            gweather_prefs_distance_enum_to_string	(GWeatherDistanceUnit distance);
+
+GWeatherTemperatureUnit gweather_prefs_parse_temperature        (const char *str,
+								 gboolean   *is_default);
+GWeatherSpeedUnit       gweather_prefs_parse_speed              (const char *str,
+								 gboolean   *is_default);
+
+const char *            gweather_prefs_get_temp_display_name		(GWeatherTemperatureUnit temp);
+const char *            gweather_prefs_get_speed_display_name		(GWeatherSpeedUnit speed);
+const char *            gweather_prefs_get_pressure_display_name	(GWeatherPressureUnit pressure);
+const char *            gweather_prefs_get_distance_display_name	(GWeatherDistanceUnit distance);
 
 #endif /* __GWEATHER_PREFS_H_ */
diff --git a/libgweather/gweather-xml.c b/libgweather/gweather-xml.c
index 3b426f8..2f9e95f 100644
--- a/libgweather/gweather-xml.c
+++ b/libgweather/gweather-xml.c
@@ -85,7 +85,7 @@ gweather_xml_parse_node (GWeatherLocation *gloc,
 			    GWEATHER_XML_COL_LOC, name,
 			    -1);
 	if (children[0] && !children[1]) {
-	    wloc = gweather_location_to_weather_location (children[0], name);
+	    wloc = _weather_location_from_gweather_location (children[0], name);
 	    gtk_tree_store_set (store, &iter,
 				GWEATHER_XML_COL_POINTER, wloc,
 				-1);
@@ -101,7 +101,7 @@ gweather_xml_parse_node (GWeatherLocation *gloc,
 	parent_loc = gweather_location_get_parent (gloc);
 	if (parent_loc && gweather_location_get_level (parent_loc) == GWEATHER_LOCATION_CITY)
 	    name = gweather_location_get_name (parent_loc);
-	wloc = gweather_location_to_weather_location (gloc, name);
+	wloc = _weather_location_from_gweather_location (gloc, name);
 	gtk_tree_store_set (store, &iter,
 			    GWEATHER_XML_COL_POINTER, wloc,
 			    -1);
@@ -151,7 +151,7 @@ free_locations (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpoin
 			    -1);
 
 	if (loc) {
-		weather_location_free (loc);
+		_weather_location_free (loc);
 		gtk_tree_store_set ((GtkTreeStore *)model, iter,
 			    GWEATHER_XML_COL_POINTER, NULL,
 			    -1);
diff --git a/libgweather/test_metar.c b/libgweather/test_metar.c
index a314ca9..3ab2ace 100644
--- a/libgweather/test_metar.c
+++ b/libgweather/test_metar.c
@@ -27,7 +27,9 @@ main (int argc, char **argv)
     GError* error = NULL;
     char buf[BUFLEN];
     int len;
-    WeatherInfo info;
+    GWeatherInfo *info;
+
+    g_type_init ();
 
     context = g_option_context_new ("- test libgweather metar parser");
     g_option_context_add_main_entries (context, entries, NULL);
@@ -54,19 +56,20 @@ main (int argc, char **argv)
 	}
 	printf ("\n%s\n", buf);
 
-	memset (&info, 0, sizeof (info));
-	info.valid = 1;
-	metar_parse (buf, &info);
-	weather_info_to_metric (&info);
+	/* a bit hackish... */
+	info = g_object_new (GWEATHER_TYPE_INFO, NULL);
+	info->priv->valid = 1;
+	metar_parse (buf, info);
+	gweather_info_to_metric (info);
 	printf ("Returned info:\n");
-	printf ("  update:   %s", ctime (&info.update));
-	printf ("  sky:      %s\n", weather_info_get_sky (&info));
-	printf ("  cond:     %s\n", weather_info_get_conditions (&info));
-	printf ("  temp:     %s\n", weather_info_get_temp (&info));
-	printf ("  dewp:     %s\n", weather_info_get_dew (&info));
-	printf ("  wind:     %s\n", weather_info_get_wind (&info));
-	printf ("  pressure: %s\n", weather_info_get_pressure (&info));
-	printf ("  vis:      %s\n", weather_info_get_visibility (&info));
+	printf ("  update:   %s", ctime (&info->priv->update));
+	printf ("  sky:      %s\n", gweather_info_get_sky (info));
+	printf ("  cond:     %s\n", gweather_info_get_conditions (info));
+	printf ("  temp:     %s\n", gweather_info_get_temp (info));
+	printf ("  dewp:     %s\n", gweather_info_get_dew (info));
+	printf ("  wind:     %s\n", gweather_info_get_wind (info));
+	printf ("  pressure: %s\n", gweather_info_get_pressure (info));
+	printf ("  vis:      %s\n", gweather_info_get_visibility (info));
 
 	// TODO: retrieve location's lat/lon to display sunrise/set times
     }
diff --git a/libgweather/test_sun_moon.c b/libgweather/test_sun_moon.c
index be65779..dc17e3f 100644
--- a/libgweather/test_sun_moon.c
+++ b/libgweather/test_sun_moon.c
@@ -10,7 +10,7 @@
 int
 main (int argc, char **argv)
 {
-    WeatherInfo     info;
+    GWeatherInfo   *info;
     GOptionContext* context;
     GError*         error = NULL;
     gdouble         latitude, longitude;
@@ -30,8 +30,9 @@ main (int argc, char **argv)
 	{ NULL }
     };
 
+    g_type_init ();
+
     memset(&location, 0, sizeof(WeatherLocation));
-    memset(&info, 0, sizeof(WeatherInfo));
 
     context = g_option_context_new ("- test libgweather sun/moon calculations");
     g_option_context_add_main_entries (context, entries, NULL);
@@ -51,35 +52,37 @@ main (int argc, char **argv)
 
     location.latitude = DEGREES_TO_RADIANS(latitude);
     location.longitude = DEGREES_TO_RADIANS(longitude);
-    location.latlon_valid = TRUE;
-    info.location = &location;
-    info.valid = TRUE;
+    /* any string will do here, just it cannot be NULL */
+    location.coordinates = "dummy";
+    info = g_object_new (GWEATHER_TYPE_INFO, NULL);
+    info->priv->location = _weather_location_clone(&location);
+    info->priv->valid = TRUE;
 
     if (gtime != NULL) {
 	//	printf(" gtime=%s\n", gtime);
 	g_date_set_parse(&gdate, gtime);
 	g_date_to_struct_tm(&gdate, &tm);
-	info.update = mktime(&tm);
+	info->priv->update = mktime(&tm);
     } else {
-	info.update = time(NULL);
+	info->priv->update = time(NULL);
     }
 
-    bsun = calc_sun_time(&info, info.update);
-    bmoon = calc_moon(&info);
+    bsun = calc_sun_time(info, info->priv->update);
+    bmoon = calc_moon(info);
 
     printf ("  Latitude %7.3f %c  Longitude %7.3f %c for %s  All times UTC\n",
 	    fabs(latitude), (latitude >= 0. ? 'N' : 'S'),
 	    fabs(longitude), (longitude >= 0. ? 'E' : 'W'),
-	    asctime(gmtime(&info.update)));
+	    asctime(gmtime(&info->priv->update)));
     printf("sunrise:   %s",
-	   (info.sunriseValid ? ctime(&info.sunrise) : "(invalid)\n"));
+	   (info->priv->sunriseValid ? ctime(&info->priv->sunrise) : "(invalid)\n"));
     printf("sunset:    %s",
-	   (info.sunsetValid ? ctime(&info.sunset)  : "(invalid)\n"));
+	   (info->priv->sunsetValid ? ctime(&info->priv->sunset)  : "(invalid)\n"));
     if (bmoon) {
-	printf("moonphase: %g\n", info.moonphase);
-	printf("moonlat:   %g\n", info.moonlatitude);
+	printf("moonphase: %g\n", info->priv->moonphase);
+	printf("moonlat:   %g\n", info->priv->moonlatitude);
 
-	if (calc_moon_phases(&info, phases)) {
+	if (calc_moon_phases(info, phases)) {
 	    printf("    New:   %s", asctime(gmtime(&phases[0])));
 	    printf("    1stQ:  %s", asctime(gmtime(&phases[1])));
 	    printf("    Full:  %s", asctime(gmtime(&phases[2])));
diff --git a/libgweather/weather-bom.c b/libgweather/weather-bom.c
index e56ba14..9636d8f 100644
--- a/libgweather/weather-bom.c
+++ b/libgweather/weather-bom.c
@@ -29,7 +29,7 @@
 static void
 bom_finish (SoupSession *session, SoupMessage *msg, gpointer data)
 {
-    WeatherInfo *info = (WeatherInfo *)data;
+    GWeatherInfo *info = (GWeatherInfo *)data;
     char *p, *rp;
 
     g_return_if_fail (info != NULL);
@@ -45,33 +45,33 @@ bom_finish (SoupSession *session, SoupMessage *msg, gpointer data)
     if (p != NULL) {
         rp = strstr (p, "The next routine forecast will be issued");
         if (rp == NULL)
-            info->forecast = g_strdup (p);
+            info->priv->forecast = g_strdup (p);
         else
-            info->forecast = g_strndup (p, rp - p);
+            info->priv->forecast = g_strndup (p, rp - p);
     }
 
-    if (info->forecast == NULL)
-        info->forecast = g_strdup (msg->response_body->data);
+    if (info->priv->forecast == NULL)
+        info->priv->forecast = g_strdup (msg->response_body->data);
 
-    g_print ("%s\n",  info->forecast);
+    g_print ("%s\n",  info->priv->forecast);
     request_done (info, TRUE);
 }
 
 void
-bom_start_open (WeatherInfo *info)
+bom_start_open (GWeatherInfo *info)
 {
     gchar *url;
     SoupMessage *msg;
     WeatherLocation *loc;
 
-    loc = info->location;
+    loc = info->priv->location;
 
     url = g_strdup_printf ("http://www.bom.gov.au/fwo/%s.txt";,
 			   loc->zone + 1);
 
     msg = soup_message_new ("GET", url);
-    soup_session_queue_message (info->session, msg, bom_finish, info);
+    soup_session_queue_message (info->priv->session, msg, bom_finish, info);
     g_free (url);
 
-    info->requests_pending++;
+    info->priv->requests_pending++;
 }
diff --git a/libgweather/weather-iwin.c b/libgweather/weather-iwin.c
index 28415b0..e929656 100644
--- a/libgweather/weather-iwin.c
+++ b/libgweather/weather-iwin.c
@@ -93,7 +93,7 @@ hasAttr (xmlNode *node, const char *attr_name, const char *attr_value)
 }
 
 static GSList *
-parseForecastXml (const char *buff, WeatherInfo *master_info)
+parseForecastXml (const char *buff, GWeatherInfo *master_info)
 {
     GSList *res = NULL;
     xmlDocPtr doc;
@@ -176,38 +176,10 @@ parseForecastXml (const char *buff, WeatherInfo *master_info)
                         int i;
 
                         for (i = 0; i < 7;  i++) {
-                            WeatherInfo *nfo = weather_info_clone (master_info);
-
-                            if (nfo) {
-                                nfo->valid = FALSE;
-                                nfo->forecast_type = FORECAST_ZONE;
-                                nfo->update = update_times [i];
-                                nfo->sky = -1;
-                                nfo->temperature_unit = TEMP_UNIT_FAHRENHEIT;
-                                nfo->temp = -1000.0;
-                                nfo->temp_min = -1000.0;
-                                nfo->temp_max = -1000.0;
-                                nfo->tempMinMaxValid = FALSE;
-                                nfo->cond.significant = FALSE;
-                                nfo->cond.phenomenon = PHENOMENON_NONE;
-                                nfo->cond.qualifier = QUALIFIER_NONE;
-                                nfo->dew = -1000.0;
-                                nfo->wind = -1;
-                                nfo->windspeed = -1;
-                                nfo->pressure = -1.0;
-                                nfo->visibility = -1.0;
-                                nfo->sunriseValid = FALSE;
-                                nfo->sunsetValid = FALSE;
-                                nfo->sunrise = 0;
-                                nfo->sunset = 0;
-                                g_free (nfo->forecast);
-                                nfo->forecast = NULL;
-				nfo->session = NULL;
-				nfo->requests_pending = 0;
-				nfo->finish_cb = NULL;
-				nfo->cb_data = NULL;
+                            GWeatherInfo *nfo = _gweather_info_new_clone (master_info);
+
+                            if (nfo)
                                 res = g_slist_append (res, nfo);
-                            }
                         }
                     }
 
@@ -222,27 +194,28 @@ parseForecastXml (const char *buff, WeatherInfo *master_info)
 
                             for (c = p->children; c && at; c = c->next) {
                                 if (isElem (c, "value")) {
-                                    WeatherInfo *nfo = (WeatherInfo *)at->data;
+                                    GWeatherInfo *nfo = (GWeatherInfo *)at->data;
+				    GWeatherInfoPrivate *priv = nfo->priv;
                                     xmlChar *val = xmlNodeGetContent (c);
 
                                     /* can pass some values as <value xsi:nil="true"/> */
                                     if (!val || !*val) {
                                         if (is_max)
-                                            nfo->temp_max = nfo->temp_min;
+                                            priv->temp_max = priv->temp_min;
                                         else
-                                            nfo->temp_min = nfo->temp_max;
+                                            priv->temp_min = priv->temp_max;
                                     } else {
                                         if (is_max)
-                                            nfo->temp_max = atof ((const char *)val);
+                                            priv->temp_max = atof ((const char *)val);
                                         else
-                                            nfo->temp_min = atof ((const char *)val);
+                                            priv->temp_min = atof ((const char *)val);
                                     }
 
                                     if (val)
                                         xmlFree (val);
 
-                                    nfo->tempMinMaxValid = nfo->tempMinMaxValid || (nfo->temp_max > -999.0 && nfo->temp_min > -999.0);
-                                    nfo->valid = nfo->tempMinMaxValid;
+                                    priv->tempMinMaxValid = priv->tempMinMaxValid || (priv->temp_max > -999.0 && priv->temp_min > -999.0);
+                                    priv->valid = priv->tempMinMaxValid;
 
                                     at = at->next;
                                 }
@@ -253,7 +226,8 @@ parseForecastXml (const char *buff, WeatherInfo *master_info)
 
                             for (c = p->children; c && at; c = c->next) {
                                 if (c->name && isElem (c, "weather-conditions")) {
-                                    WeatherInfo *nfo = at->data;
+                                    GWeatherInfo *nfo = at->data;
+				    GWeatherInfoPrivate *priv = nfo->priv;
                                     xmlChar *val = xmlGetProp (c, XC "weather-summary");
 
                                     if (val && nfo) {
@@ -262,7 +236,7 @@ parseForecastXml (const char *buff, WeatherInfo *master_info)
                                         int i;
                                         struct _ph_list {
                                             const char *name;
-                                            WeatherConditionPhenomenon ph;
+                                            GWeatherConditionPhenomenon ph;
                                         } ph_list[] = {
                                             { "Ice Crystals", PHENOMENON_ICE_CRYSTALS } ,
                                             { "Volcanic Ash", PHENOMENON_VOLCANIC_ASH } ,
@@ -290,7 +264,7 @@ parseForecastXml (const char *buff, WeatherInfo *master_info)
                                         };
                                         struct _sky_list {
                                             const char *name;
-                                            WeatherSky sky;
+                                            GWeatherSky sky;
                                         } sky_list[] = {
                                             { "Mostly Sunny", SKY_BROKEN } ,
                                             { "Mostly Clear", SKY_BROKEN } ,
@@ -304,20 +278,20 @@ parseForecastXml (const char *buff, WeatherInfo *master_info)
                                             { "Snow", SKY_SCATTERED }
                                         };
 
-                                        nfo->valid = TRUE;
-                                        g_free (nfo->forecast);
-                                        nfo->forecast = g_strdup ((const char *)val);
+                                        priv->valid = TRUE;
+                                        g_free (priv->forecast);
+                                        priv->forecast = g_strdup ((const char *)val);
 
                                         for (i = 0; i < G_N_ELEMENTS (ph_list); i++) {
                                             if (strstr ((const char *)val, ph_list [i].name)) {
-                                                nfo->cond.phenomenon = ph_list [i].ph;
+                                                priv->cond.phenomenon = ph_list [i].ph;
                                                 break;
                                             }
                                         }
 
                                         for (i = 0; i < G_N_ELEMENTS (sky_list); i++) {
                                             if (strstr ((const char *)val, sky_list [i].name)) {
-                                                nfo->sky = sky_list [i].sky;
+                                                priv->sky = sky_list [i].sky;
                                                 break;
                                             }
                                         }
@@ -339,18 +313,19 @@ parseForecastXml (const char *buff, WeatherInfo *master_info)
                         /* Remove invalid forecast data from the list.
                            They should be all valid or all invalid. */
                         for (r = res; r; r = r->next) {
-                            WeatherInfo *nfo = r->data;
+                            GWeatherInfo *nfo = r->data;
+			    GWeatherInfoPrivate *priv = nfo->priv;
 
-                            if (!nfo || !nfo->valid) {
+                            if (!nfo || !priv->valid) {
                                 if (r->data)
-                                    weather_info_free (r->data);
+                                    g_object_unref (r->data);
 
                                 r->data = NULL;
                             } else {
                                 have_any = TRUE;
 
-                                if (nfo->tempMinMaxValid)
-                                    nfo->temp = (nfo->temp_min + nfo->temp_max) / 2.0;
+                                if (priv->tempMinMaxValid)
+                                    priv->temp = (priv->temp_min + priv->temp_max) / 2.0;
                             }
                         }
 
@@ -382,7 +357,8 @@ parseForecastXml (const char *buff, WeatherInfo *master_info)
 static void
 iwin_finish (SoupSession *session, SoupMessage *msg, gpointer data)
 {
-    WeatherInfo *info = (WeatherInfo *)data;
+    GWeatherInfo *info = (GWeatherInfo *)data;
+    GWeatherInfoPrivate *priv;
 
     g_return_if_fail (info != NULL);
 
@@ -394,39 +370,44 @@ iwin_finish (SoupSession *session, SoupMessage *msg, gpointer data)
         return;
     }
 
-    if (info->forecast_type == FORECAST_LIST)
-        info->forecast_list = parseForecastXml (msg->response_body->data, info);
+    priv = info->priv;
+
+    if (priv->forecast_type == FORECAST_LIST)
+        priv->forecast_list = parseForecastXml (msg->response_body->data, info);
     else
-        info->forecast = formatWeatherMsg (g_strdup (msg->response_body->data));
+        priv->forecast = formatWeatherMsg (g_strdup (msg->response_body->data));
 
     request_done (info, TRUE);
 }
 
 /* Get forecast into newly alloc'ed string */
 void
-iwin_start_open (WeatherInfo *info)
+iwin_start_open (GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv;
     gchar *url, *state, *zone;
     WeatherLocation *loc;
     SoupMessage *msg;
 
     g_return_if_fail (info != NULL);
-    loc = info->location;
+
+    priv = info->priv;
+    loc = priv->location;
     g_return_if_fail (loc != NULL);
 
-    if (loc->zone[0] == '-' && (info->forecast_type != FORECAST_LIST || !loc->latlon_valid))
+    if (loc->zone[0] == '-' && (priv->forecast_type != FORECAST_LIST || loc->coordinates == NULL))
         return;
 
-    if (info->forecast) {
-        g_free (info->forecast);
-        info->forecast = NULL;
+    if (priv->forecast) {
+        g_free (priv->forecast);
+        priv->forecast = NULL;
     }
 
     free_forecast_list (info);    
 
-    if (info->forecast_type == FORECAST_LIST) {
+    if (priv->forecast_type == FORECAST_LIST) {
         /* see the description here: http://www.weather.gov/forecasts/xml/ */
-        if (loc->latlon_valid) {
+        if (loc->coordinates != NULL) {
             struct tm tm;
             time_t now = time (NULL);
 
@@ -437,9 +418,9 @@ iwin_start_open (WeatherInfo *info)
 
             msg = soup_message_new ("GET", url);
             g_free (url);
-            soup_session_queue_message (info->session, msg, iwin_finish, info);
+            soup_session_queue_message (priv->session, msg, iwin_finish, info);
 
-            info->requests_pending++;
+            priv->requests_pending++;
         }
 
         return;
@@ -469,7 +450,7 @@ iwin_start_open (WeatherInfo *info)
     
     msg = soup_message_new ("GET", url);
     g_free (url);
-    soup_session_queue_message (info->session, msg, iwin_finish, info);
+    soup_session_queue_message (priv->session, msg, iwin_finish, info);
 
-    info->requests_pending++;
+    priv->requests_pending++;
 }
diff --git a/libgweather/weather-met.c b/libgweather/weather-met.c
index 62275ac..0057413 100644
--- a/libgweather/weather-met.c
+++ b/libgweather/weather-met.c
@@ -150,7 +150,7 @@ met_parse (const gchar *meto)
 static void
 met_finish (SoupSession *session, SoupMessage *msg, gpointer data)
 {
-    WeatherInfo *info = (WeatherInfo *)data;
+    GWeatherInfo *info = (GWeatherInfo *)data;
 
     g_return_if_fail (info != NULL);
 
@@ -161,23 +161,23 @@ met_finish (SoupSession *session, SoupMessage *msg, gpointer data)
         return;
     }
 
-    info->forecast = met_parse (msg->response_body->data);
+    info->priv->forecast = met_parse (msg->response_body->data);
     request_done (info, TRUE);
 }
 
 void
-metoffice_start_open (WeatherInfo *info)
+metoffice_start_open (GWeatherInfo *info)
 {
     gchar *url;
     SoupMessage *msg;
     WeatherLocation *loc;
 
-    loc = info->location;
+    loc = info->priv->location;
     url = g_strdup_printf ("http://www.metoffice.gov.uk/weather/uk/%s/%s_forecast_weather_noscript.html";, loc->zone + 1, loc->zone + 1);
 
     msg = soup_message_new ("GET", url);
-    soup_session_queue_message (info->session, msg, met_finish, info);
+    soup_session_queue_message (info->priv->session, msg, met_finish, info);
     g_free (url);
    
-    info->requests_pending++;
+    info->priv->requests_pending++;
 }
diff --git a/libgweather/weather-metar.c b/libgweather/weather-metar.c
index 325dbe8..3630646 100644
--- a/libgweather/weather-metar.c
+++ b/libgweather/weather-metar.c
@@ -73,22 +73,25 @@ make_time (gint utcDate, gint utcHour, gint utcMin)
 }
 
 static void
-metar_tok_time (gchar *tokp, WeatherInfo *info)
+metar_tok_time (gchar *tokp, GWeatherInfo *info)
 {
     gint day, hr, min;
 
     sscanf (tokp, "%2u%2u%2u", &day, &hr, &min);
-    info->update = make_time (day, hr, min);
+    info->priv->update = make_time (day, hr, min);
 }
 
 static void
-metar_tok_wind (gchar *tokp, WeatherInfo *info)
+metar_tok_wind (gchar *tokp, GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv;
     gchar sdir[4], sspd[4], sgust[4];
     gint dir, spd = -1;
     gchar *gustp;
     size_t glen;
 
+    priv = info->priv;
+
     strncpy (sdir, tokp, 3);
     sdir[3] = 0;
     dir = (!strcmp (sdir, "VRB")) ? -1 : atoi (sdir);
@@ -108,96 +111,102 @@ metar_tok_wind (gchar *tokp, WeatherInfo *info)
     }
 
     if (!strcmp (tokp, "MPS"))
-	info->windspeed = WINDSPEED_MS_TO_KNOTS ((WeatherWindSpeed)spd);
+	priv->windspeed = WINDSPEED_MS_TO_KNOTS ((GWeatherWindSpeed)spd);
     else
-	info->windspeed = (WeatherWindSpeed)spd;
+	priv->windspeed = (GWeatherWindSpeed)spd;
 
     if ((349 <= dir) || (dir <= 11))
-        info->wind = WIND_N;
+        priv->wind = WIND_N;
     else if ((12 <= dir) && (dir <= 33))
-        info->wind = WIND_NNE;
+        priv->wind = WIND_NNE;
     else if ((34 <= dir) && (dir <= 56))
-        info->wind = WIND_NE;
+        priv->wind = WIND_NE;
     else if ((57 <= dir) && (dir <= 78))
-        info->wind = WIND_ENE;
+        priv->wind = WIND_ENE;
     else if ((79 <= dir) && (dir <= 101))
-        info->wind = WIND_E;
+        priv->wind = WIND_E;
     else if ((102 <= dir) && (dir <= 123))
-        info->wind = WIND_ESE;
+        priv->wind = WIND_ESE;
     else if ((124 <= dir) && (dir <= 146))
-        info->wind = WIND_SE;
+        priv->wind = WIND_SE;
     else if ((147 <= dir) && (dir <= 168))
-        info->wind = WIND_SSE;
+        priv->wind = WIND_SSE;
     else if ((169 <= dir) && (dir <= 191))
-        info->wind = WIND_S;
+        priv->wind = WIND_S;
     else if ((192 <= dir) && (dir <= 213))
-        info->wind = WIND_SSW;
+        priv->wind = WIND_SSW;
     else if ((214 <= dir) && (dir <= 236))
-        info->wind = WIND_SW;
+        priv->wind = WIND_SW;
     else if ((237 <= dir) && (dir <= 258))
-        info->wind = WIND_WSW;
+        priv->wind = WIND_WSW;
     else if ((259 <= dir) && (dir <= 281))
-        info->wind = WIND_W;
+        priv->wind = WIND_W;
     else if ((282 <= dir) && (dir <= 303))
-        info->wind = WIND_WNW;
+        priv->wind = WIND_WNW;
     else if ((304 <= dir) && (dir <= 326))
-        info->wind = WIND_NW;
+        priv->wind = WIND_NW;
     else if ((327 <= dir) && (dir <= 348))
-        info->wind = WIND_NNW;
+        priv->wind = WIND_NNW;
 }
 
 static void
-metar_tok_vis (gchar *tokp, WeatherInfo *info)
+metar_tok_vis (gchar *tokp, GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv;
     gchar *pfrac, *pend, *psp;
     gchar sval[6];
     gint num, den, val;
 
+    priv = info->priv;
+
     memset (sval, 0, sizeof (sval));
 
     if (!strcmp (tokp,"CAVOK")) {
         // "Ceiling And Visibility OK": visibility >= 10 KM
-        info->visibility=10000. / VISIBILITY_SM_TO_M (1.);
-        info->sky = SKY_CLEAR;
+        priv->visibility=10000. / VISIBILITY_SM_TO_M (1.);
+        priv->sky = SKY_CLEAR;
     } else if (0 != (pend = strstr (tokp, "SM"))) {
         // US observation: field ends with "SM"
         pfrac = strchr (tokp, '/');
         if (pfrac) {
 	    if (*tokp == 'M') {
-	        info->visibility = 0.001;
+	        priv->visibility = 0.001;
 	    } else {
 	        num = (*(pfrac - 1) - '0');
 		strncpy (sval, pfrac + 1, pend - pfrac - 1);
 		den = atoi (sval);
-		info->visibility =
-		    ((WeatherVisibility)num / ((WeatherVisibility)den));
+		priv->visibility =
+		    ((GWeatherVisibility)num / ((GWeatherVisibility)den));
 
 		psp = strchr (tokp, ' ');
 		if (psp) {
 		    *psp = '\0';
 		    val = atoi (tokp);
-		    info->visibility += (WeatherVisibility)val;
+		    priv->visibility += (GWeatherVisibility)val;
 		}
 	    }
 	} else {
 	    strncpy (sval, tokp, pend - tokp);
             val = atoi (sval);
-            info->visibility = (WeatherVisibility)val;
+            priv->visibility = (GWeatherVisibility)val;
 	}
     } else {
         // International observation: NNNN(DD NNNNDD)?
         // For now: use only the minimum visibility and ignore its direction
         strncpy (sval, tokp, strspn (tokp, CONST_DIGITS));
 	val = atoi (sval);
-	info->visibility = (WeatherVisibility)val / VISIBILITY_SM_TO_M (1.);
+	priv->visibility = (GWeatherVisibility)val / VISIBILITY_SM_TO_M (1.);
     }
 }
 
 static void
-metar_tok_cloud (gchar *tokp, WeatherInfo *info)
+metar_tok_cloud (gchar *tokp, GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv;
     gchar stype[4], salt[4];
 
+    priv = info->priv;
+
     strncpy (stype, tokp, 3);
     stype[3] = 0;
     if (strlen (tokp) == 6) {
@@ -206,25 +215,27 @@ metar_tok_cloud (gchar *tokp, WeatherInfo *info)
     }
 
     if (!strcmp (stype, "CLR")) {
-        info->sky = SKY_CLEAR;
+        priv->sky = SKY_CLEAR;
     } else if (!strcmp (stype, "SKC")) {
-        info->sky = SKY_CLEAR;
+        priv->sky = SKY_CLEAR;
     } else if (!strcmp (stype, "NSC")) {
-        info->sky = SKY_CLEAR;
+        priv->sky = SKY_CLEAR;
     } else if (!strcmp (stype, "BKN")) {
-        info->sky = SKY_BROKEN;
+        priv->sky = SKY_BROKEN;
     } else if (!strcmp (stype, "SCT")) {
-        info->sky = SKY_SCATTERED;
+        priv->sky = SKY_SCATTERED;
     } else if (!strcmp (stype, "FEW")) {
-        info->sky = SKY_FEW;
+        priv->sky = SKY_FEW;
     } else if (!strcmp (stype, "OVC")) {
-        info->sky = SKY_OVERCAST;
+        priv->sky = SKY_OVERCAST;
     }
 }
 
 static void
-metar_tok_pres (gchar *tokp, WeatherInfo *info)
+metar_tok_pres (gchar *tokp, GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv = info->priv;
+
     if (*tokp == 'A') {
         gchar sintg[3], sfract[3];
         gint intg, fract;
@@ -237,7 +248,7 @@ metar_tok_pres (gchar *tokp, WeatherInfo *info)
         sfract[2] = 0;
         fract = atoi (sfract);
 
-        info->pressure = (WeatherPressure)intg + (((WeatherPressure)fract)/100.0);
+        priv->pressure = (GWeatherPressure)intg + (((GWeatherPressure)fract)/100.0);
     } else {  /* *tokp == 'Q' */
         gchar spres[5];
         gint pres;
@@ -246,36 +257,42 @@ metar_tok_pres (gchar *tokp, WeatherInfo *info)
         spres[4] = 0;
         pres = atoi (spres);
 
-        info->pressure = PRESSURE_MBAR_TO_INCH ((WeatherPressure)pres);
+        priv->pressure = PRESSURE_MBAR_TO_INCH ((GWeatherPressure)pres);
     }
 }
 
 static void
-metar_tok_temp (gchar *tokp, WeatherInfo *info)
+metar_tok_temp (gchar *tokp, GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv;
     gchar *ptemp, *pdew, *psep;
 
+    priv = info->priv;
+
     psep = strchr (tokp, '/');
     *psep = 0;
     ptemp = tokp;
     pdew = psep + 1;
 
-    info->temp = (*ptemp == 'M') ? TEMP_C_TO_F (-atoi (ptemp + 1))
+    priv->temp = (*ptemp == 'M') ? TEMP_C_TO_F (-atoi (ptemp + 1))
 	: TEMP_C_TO_F (atoi (ptemp));
     if (*pdew) {
-	info->dew = (*pdew == 'M') ? TEMP_C_TO_F (-atoi (pdew + 1))
+	priv->dew = (*pdew == 'M') ? TEMP_C_TO_F (-atoi (pdew + 1))
 	    : TEMP_C_TO_F (atoi (pdew));
     } else {
-	info->dew = -1000.0;
+	priv->dew = -1000.0;
     }
 }
 
 static void
-metar_tok_cond (gchar *tokp, WeatherInfo *info)
+metar_tok_cond (gchar *tokp, GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv;
     gchar squal[3], sphen[4];
     gchar *pphen;
 
+    priv = info->priv;
+
     if ((strlen (tokp) > 3) && ((*tokp == '+') || (*tokp == '-')))
         ++tokp;   /* FIX */
 
@@ -295,90 +312,90 @@ metar_tok_cond (gchar *tokp, WeatherInfo *info)
     sphen[sizeof (sphen)-1] = '\0';
 
     /* Defaults */
-    info->cond.qualifier = QUALIFIER_NONE;
-    info->cond.phenomenon = PHENOMENON_NONE;
-    info->cond.significant = FALSE;
+    priv->cond.qualifier = QUALIFIER_NONE;
+    priv->cond.phenomenon = PHENOMENON_NONE;
+    priv->cond.significant = FALSE;
 
     if (!strcmp (squal, "")) {
-        info->cond.qualifier = QUALIFIER_MODERATE;
+        priv->cond.qualifier = QUALIFIER_MODERATE;
     } else if (!strcmp (squal, "-")) {
-        info->cond.qualifier = QUALIFIER_LIGHT;
+        priv->cond.qualifier = QUALIFIER_LIGHT;
     } else if (!strcmp (squal, "+")) {
-        info->cond.qualifier = QUALIFIER_HEAVY;
+        priv->cond.qualifier = QUALIFIER_HEAVY;
     } else if (!strcmp (squal, "VC")) {
-        info->cond.qualifier = QUALIFIER_VICINITY;
+        priv->cond.qualifier = QUALIFIER_VICINITY;
     } else if (!strcmp (squal, "MI")) {
-        info->cond.qualifier = QUALIFIER_SHALLOW;
+        priv->cond.qualifier = QUALIFIER_SHALLOW;
     } else if (!strcmp (squal, "BC")) {
-        info->cond.qualifier = QUALIFIER_PATCHES;
+        priv->cond.qualifier = QUALIFIER_PATCHES;
     } else if (!strcmp (squal, "PR")) {
-        info->cond.qualifier = QUALIFIER_PARTIAL;
+        priv->cond.qualifier = QUALIFIER_PARTIAL;
     } else if (!strcmp (squal, "TS")) {
-        info->cond.qualifier = QUALIFIER_THUNDERSTORM;
+        priv->cond.qualifier = QUALIFIER_THUNDERSTORM;
     } else if (!strcmp (squal, "BL")) {
-        info->cond.qualifier = QUALIFIER_BLOWING;
+        priv->cond.qualifier = QUALIFIER_BLOWING;
     } else if (!strcmp (squal, "SH")) {
-        info->cond.qualifier = QUALIFIER_SHOWERS;
+        priv->cond.qualifier = QUALIFIER_SHOWERS;
     } else if (!strcmp (squal, "DR")) {
-        info->cond.qualifier = QUALIFIER_DRIFTING;
+        priv->cond.qualifier = QUALIFIER_DRIFTING;
     } else if (!strcmp (squal, "FZ")) {
-        info->cond.qualifier = QUALIFIER_FREEZING;
+        priv->cond.qualifier = QUALIFIER_FREEZING;
     } else {
         return;
     }
 
     if (!strcmp (sphen, "DZ")) {
-        info->cond.phenomenon = PHENOMENON_DRIZZLE;
+        priv->cond.phenomenon = PHENOMENON_DRIZZLE;
     } else if (!strcmp (sphen, "RA")) {
-        info->cond.phenomenon = PHENOMENON_RAIN;
+        priv->cond.phenomenon = PHENOMENON_RAIN;
     } else if (!strcmp (sphen, "SN")) {
-        info->cond.phenomenon = PHENOMENON_SNOW;
+        priv->cond.phenomenon = PHENOMENON_SNOW;
     } else if (!strcmp (sphen, "SG")) {
-        info->cond.phenomenon = PHENOMENON_SNOW_GRAINS;
+        priv->cond.phenomenon = PHENOMENON_SNOW_GRAINS;
     } else if (!strcmp (sphen, "IC")) {
-        info->cond.phenomenon = PHENOMENON_ICE_CRYSTALS;
+        priv->cond.phenomenon = PHENOMENON_ICE_CRYSTALS;
     } else if (!strcmp (sphen, "PE")) {
-        info->cond.phenomenon = PHENOMENON_ICE_PELLETS;
+        priv->cond.phenomenon = PHENOMENON_ICE_PELLETS;
     } else if (!strcmp (sphen, "GR")) {
-        info->cond.phenomenon = PHENOMENON_HAIL;
+        priv->cond.phenomenon = PHENOMENON_HAIL;
     } else if (!strcmp (sphen, "GS")) {
-        info->cond.phenomenon = PHENOMENON_SMALL_HAIL;
+        priv->cond.phenomenon = PHENOMENON_SMALL_HAIL;
     } else if (!strcmp (sphen, "UP")) {
-        info->cond.phenomenon = PHENOMENON_UNKNOWN_PRECIPITATION;
+        priv->cond.phenomenon = PHENOMENON_UNKNOWN_PRECIPITATION;
     } else if (!strcmp (sphen, "BR")) {
-        info->cond.phenomenon = PHENOMENON_MIST;
+        priv->cond.phenomenon = PHENOMENON_MIST;
     } else if (!strcmp (sphen, "FG")) {
-        info->cond.phenomenon = PHENOMENON_FOG;
+        priv->cond.phenomenon = PHENOMENON_FOG;
     } else if (!strcmp (sphen, "FU")) {
-        info->cond.phenomenon = PHENOMENON_SMOKE;
+        priv->cond.phenomenon = PHENOMENON_SMOKE;
     } else if (!strcmp (sphen, "VA")) {
-        info->cond.phenomenon = PHENOMENON_VOLCANIC_ASH;
+        priv->cond.phenomenon = PHENOMENON_VOLCANIC_ASH;
     } else if (!strcmp (sphen, "SA")) {
-        info->cond.phenomenon = PHENOMENON_SAND;
+        priv->cond.phenomenon = PHENOMENON_SAND;
     } else if (!strcmp (sphen, "HZ")) {
-        info->cond.phenomenon = PHENOMENON_HAZE;
+        priv->cond.phenomenon = PHENOMENON_HAZE;
     } else if (!strcmp (sphen, "PY")) {
-        info->cond.phenomenon = PHENOMENON_SPRAY;
+        priv->cond.phenomenon = PHENOMENON_SPRAY;
     } else if (!strcmp (sphen, "DU")) {
-        info->cond.phenomenon = PHENOMENON_DUST;
+        priv->cond.phenomenon = PHENOMENON_DUST;
     } else if (!strcmp (sphen, "SQ")) {
-        info->cond.phenomenon = PHENOMENON_SQUALL;
+        priv->cond.phenomenon = PHENOMENON_SQUALL;
     } else if (!strcmp (sphen, "SS")) {
-        info->cond.phenomenon = PHENOMENON_SANDSTORM;
+        priv->cond.phenomenon = PHENOMENON_SANDSTORM;
     } else if (!strcmp (sphen, "DS")) {
-        info->cond.phenomenon = PHENOMENON_DUSTSTORM;
+        priv->cond.phenomenon = PHENOMENON_DUSTSTORM;
     } else if (!strcmp (sphen, "PO")) {
-        info->cond.phenomenon = PHENOMENON_DUST_WHIRLS;
+        priv->cond.phenomenon = PHENOMENON_DUST_WHIRLS;
     } else if (!strcmp (sphen, "+FC")) {
-        info->cond.phenomenon = PHENOMENON_TORNADO;
+        priv->cond.phenomenon = PHENOMENON_TORNADO;
     } else if (!strcmp (sphen, "FC")) {
-        info->cond.phenomenon = PHENOMENON_FUNNEL_CLOUD;
+        priv->cond.phenomenon = PHENOMENON_FUNNEL_CLOUD;
     } else {
         return;
     }
 
-    if ((info->cond.qualifier != QUALIFIER_NONE) || (info->cond.phenomenon != PHENOMENON_NONE))
-        info->cond.significant = TRUE;
+    if ((priv->cond.qualifier != QUALIFIER_NONE) || (priv->cond.phenomenon != PHENOMENON_NONE))
+        priv->cond.significant = TRUE;
 }
 
 #define TIME_RE_STR  "([0-9]{6})Z"
@@ -399,7 +416,7 @@ metar_tok_cond (gchar *tokp, WeatherInfo *info)
 #define RE_SUFFIX ")( |$)"
 
 static regex_t metar_re[RE_NUM];
-static void (*metar_f[RE_NUM]) (gchar *tokp, WeatherInfo *info);
+static void (*metar_f[RE_NUM]) (gchar *tokp, GWeatherInfo *info);
 
 static void
 metar_init_re (void)
@@ -427,7 +444,7 @@ metar_init_re (void)
 }
 
 gboolean
-metar_parse (gchar *metar, WeatherInfo *info)
+metar_parse (gchar *metar, GWeatherInfo *info)
 {
     gchar *p;
     //gchar *rmk;
@@ -488,17 +505,20 @@ metar_parse (gchar *metar, WeatherInfo *info)
 static void
 metar_finish (SoupSession *session, SoupMessage *msg, gpointer data)
 {
-    WeatherInfo *info = (WeatherInfo *)data;
+    GWeatherInfo *info = (GWeatherInfo *)data;
+    GWeatherInfoPrivate *priv;
     WeatherLocation *loc;
     const gchar *p, *eoln;
     gchar *searchkey, *metar;
     gboolean success = FALSE;
 
     g_return_if_fail (info != NULL);
+
+    priv = info->priv;
    
     if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
 	if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code))
-	    info->network_error = TRUE;
+	    priv->network_error = TRUE;
 	else {
 	    /* Translators: %d is an error code, and %s the error string */
 	    g_warning (_("Failed to get METAR data: %d %s.\n"),
@@ -508,7 +528,7 @@ metar_finish (SoupSession *session, SoupMessage *msg, gpointer data)
 	return;
     }
 
-    loc = info->location;
+    loc = priv->location;
 
     searchkey = g_strdup_printf ("\n%s", loc->code);
     p = strstr (msg->response_body->data, searchkey);
@@ -527,23 +547,27 @@ metar_finish (SoupSession *session, SoupMessage *msg, gpointer data)
 	 * most likely it is a wifi hotspot login page. Call that a
 	 * network error.
 	 */
-	info->network_error = TRUE;
+	priv->network_error = TRUE;
     }
 
-    info->valid = success;
+    priv->valid = success;
     request_done (info, TRUE);
 }
 
 /* Read current conditions and fill in info structure */
 void
-metar_start_open (WeatherInfo *info)
+metar_start_open (GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv;
     WeatherLocation *loc;
     SoupMessage *msg;
 
     g_return_if_fail (info != NULL);
-    info->valid = info->network_error = FALSE;
-    loc = info->location;
+
+    priv = info->priv;
+
+    priv->valid = priv->network_error = FALSE;
+    loc = priv->location;
     if (loc == NULL) {
 	g_warning (_("WeatherInfo missing location"));
 	return;
@@ -553,7 +577,7 @@ metar_start_open (WeatherInfo *info)
 	"GET", "http://weather.noaa.gov/cgi-bin/mgetmetar.pl";,
 	"cccc", loc->code,
 	NULL);
-    soup_session_queue_message (info->session, msg, metar_finish, info);
+    soup_session_queue_message (priv->session, msg, metar_finish, info);
 
-    info->requests_pending++;
+    priv->requests_pending++;
 }
diff --git a/libgweather/weather-moon.c b/libgweather/weather-moon.c
index e6a5cde..db3ff8a 100644
--- a/libgweather/weather-moon.c
+++ b/libgweather/weather-moon.c
@@ -50,19 +50,8 @@
 #define LUNAR_PROGRESSION	13.176358
 #define LUNAR_INCLINATION	DEGREES_TO_RADIANS(5.145396)
 
-/**
- * calc_moon:
- * @info:  WeatherInfo containing time_t of interest.  The
- *    values moonphase, moonlatitude and moonValid are updated
- *    on success.
- *
- * Returns: gboolean indicating success or failure.
- *    moonphase is expressed as degrees where '0' is a new moon,
- *    '90' is first quarter, etc.
- */
-
-gboolean
-calc_moon (WeatherInfo *info)
+static gboolean
+calc_moon_internal (time_t update, gdouble *moonphase, gdouble *moonlatitude)
 {
     time_t  t;
     gdouble ra_h;
@@ -81,7 +70,7 @@ calc_moon (WeatherInfo *info)
      * The comments refer to the enumerated steps to calculate the
      * position of the moon (section 65 of above reference)
      */
-    t = info->update;
+    t = update;
     ndays = EPOCH_TO_J2000(t) / 86400.;
     sunMeanAnom_d = fmod (MEAN_ECLIPTIC_LONGITUDE (ndays) - PERIGEE_LONGITUDE (ndays),
 			  360.);
@@ -126,17 +115,36 @@ calc_moon (WeatherInfo *info)
     /*
      * The phase is the angle from the sun's longitude to the moon's 
      */
-    info->moonphase =
-        fmod (15.*ra_h - RADIANS_TO_DEGREES (sunEclipLongitude (info->update)),
+    *moonphase =
+        fmod (15.*ra_h - RADIANS_TO_DEGREES (sunEclipLongitude (update)),
 	      360.);
-    if (info->moonphase < 0)
-        info->moonphase += 360;
-    info->moonlatitude = RADIANS_TO_DEGREES (decl_r);
-    info->moonValid = TRUE;
+    if (*moonphase < 0)
+        *moonphase += 360;
+    *moonlatitude = RADIANS_TO_DEGREES (decl_r);
 
     return TRUE;
 }
 
+/**
+ * calc_moon:
+ * @info:  WeatherInfo containing time_t of interest.  The
+ *    values moonphase, moonlatitude and moonValid are updated
+ *    on success.
+ *
+ * Returns: gboolean indicating success or failure.
+ *    moonphase is expressed as degrees where '0' is a new moon,
+ *    '90' is first quarter, etc.
+ */
+
+gboolean
+calc_moon (GWeatherInfo *info)
+{
+    GWeatherInfoPrivate *priv = info->priv;
+    return priv->moonValid = calc_moon_internal (priv->update,
+						 &priv->moonphase,
+						 &priv->moonlatitude);
+}
+
 
 /**
  * calc_moon_phases:
@@ -149,9 +157,12 @@ calc_moon (WeatherInfo *info)
  */
 
 gboolean
-calc_moon_phases (WeatherInfo *info, time_t *phases)
+calc_moon_phases (GWeatherInfo *info, time_t *phases)
 {
-    WeatherInfo temp;
+    GWeatherInfoPrivate *priv;
+    time_t      tmp_update;
+    gdouble     tmp_moonphase;
+    gdouble     tmp_moonlatitude;
     time_t      *ptime;
     int         idx;
     gdouble     advance;
@@ -159,21 +170,21 @@ calc_moon_phases (WeatherInfo *info, time_t *phases)
     time_t      dtime;
 
     g_return_val_if_fail (info != NULL &&
-			  (info->moonValid || calc_moon (info)),
+			  (info->priv->moonValid || calc_moon (info)),
 			  FALSE);
 
+    priv = info->priv;
     ptime = phases;
-    memset(&temp, 0, sizeof(WeatherInfo));
 
     for (idx = 0; idx < 4; idx++) {
-	temp.update = info->update;
-	temp.moonphase = info->moonphase;
+	tmp_update = priv->update;
+	tmp_moonphase = priv->moonphase;
 
 	/*
 	 * First estimate on how far the moon needs to advance
 	 * to get to the required phase
 	 */
-	advance = (idx * 90.) - info->moonphase;
+	advance = (idx * 90.) - priv->moonphase;
 	if (advance < 0.)
 	    advance += 360.;
 
@@ -182,16 +193,16 @@ calc_moon_phases (WeatherInfo *info, time_t *phases)
 	    dtime = advance / LUNAR_PROGRESSION * 86400.;
 	    if ((dtime > -10) && (dtime < 10))
 		break;
-	    temp.update += dtime;
-	    (void)calc_moon (&temp);
+	    tmp_update += dtime;
+	    (void)calc_moon_internal (tmp_update, &tmp_moonphase, &tmp_moonlatitude);
 
-	    if (idx == 0 && temp.moonphase > 180.) {
-		advance = 360. - temp.moonphase;
+	    if (idx == 0 && tmp_moonphase > 180.) {
+		advance = 360. - tmp_moonphase;
 	    } else {
-		advance = (idx * 90.) - temp.moonphase;
+		advance = (idx * 90.) - tmp_moonphase;
 	    }
 	}
-	*ptime++ = temp.update;
+	*ptime++ = tmp_update;
     }
 
     return TRUE;
diff --git a/libgweather/weather-priv.h b/libgweather/weather-priv.h
index e8b9dce..0d89cfb 100644
--- a/libgweather/weather-priv.h
+++ b/libgweather/weather-priv.h
@@ -46,35 +46,53 @@ const char *gweather_dpgettext (const char *context, const char *str) G_GNUC_FOR
 
 #define WEATHER_LOCATION_CODE_LEN 4
 
-WeatherLocation *gweather_location_to_weather_location (GWeatherLocation *gloc,
-							const char *name);
+/* Why we have this in code?
+   (at least, it's not exposed in API anymore)
+*/
+typedef struct {
+    gchar *name;
+    gchar *code;
+    gchar *zone;
+    gchar *radar;
+    gchar *coordinates;
+    gdouble  latitude;
+    gdouble  longitude;
+    gchar *country_code;
+    gchar *tz_hint;
+} WeatherLocation;
+
+WeatherLocation *       _weather_location_from_gweather_location (GWeatherLocation *gloc, const gchar *name);
+
+WeatherLocation *	_weather_location_new 	(const gchar *trans_name,
+						 const gchar *code,
+						 const gchar *zone,
+						 const gchar *radar,
+						 const gchar *coordinates,
+						 const gchar *country_code,
+						 const gchar *tz_hint);
+WeatherLocation *	_weather_location_clone	(const WeatherLocation *location);
+void			_weather_location_free	(WeatherLocation *location);
+gboolean		_weather_location_equal	(const WeatherLocation *location1,
+						 const WeatherLocation *location2);
 
 /*
  * Weather information.
  */
 
-struct _WeatherConditions {
-    gboolean significant;
-    WeatherConditionPhenomenon phenomenon;
-    WeatherConditionQualifier qualifier;
-};
-
-typedef struct _WeatherConditions WeatherConditions;
-
-typedef gdouble WeatherTemperature;
-typedef gdouble WeatherHumidity;
-typedef gdouble WeatherWindSpeed;
-typedef gdouble WeatherPressure;
-typedef gdouble WeatherVisibility;
-typedef time_t WeatherUpdate;
+typedef gdouble GWeatherTemperature;
+typedef gdouble GWeatherHumidity;
+typedef gdouble GWeatherWindSpeed;
+typedef gdouble GWeatherPressure;
+typedef gdouble GWeatherVisibility;
+typedef time_t GWeatherUpdate;
 
-struct _WeatherInfo {
-    WeatherForecastType forecast_type;
+struct _GWeatherInfoPrivate {
+    GWeatherForecastType forecast_type;
 
-    TempUnit temperature_unit;
-    SpeedUnit speed_unit;
-    PressureUnit pressure_unit;
-    DistanceUnit distance_unit;
+    GWeatherTemperatureUnit temperature_unit;
+    GWeatherSpeedUnit speed_unit;
+    GWeatherPressureUnit pressure_unit;
+    GWeatherDistanceUnit distance_unit;
 
     gboolean valid;
     gboolean network_error;
@@ -85,21 +103,22 @@ struct _WeatherInfo {
     gboolean moonValid;
     gboolean tempMinMaxValid;
     WeatherLocation *location;
-    WeatherUpdate update;
-    WeatherSky sky;
-    WeatherConditions cond;
-    WeatherTemperature temp;
-    WeatherTemperature temp_min;
-    WeatherTemperature temp_max;
-    WeatherTemperature dew;
-    WeatherWindDirection wind;
-    WeatherWindSpeed windspeed;
-    WeatherPressure pressure;
-    WeatherVisibility visibility;
-    WeatherUpdate sunrise;
-    WeatherUpdate sunset;
-    WeatherMoonPhase moonphase;
-    WeatherMoonLatitude moonlatitude;
+    GWeatherLocation *glocation;
+    GWeatherUpdate update;
+    GWeatherSky sky;
+    GWeatherConditions cond;
+    GWeatherTemperature temp;
+    GWeatherTemperature temp_min;
+    GWeatherTemperature temp_max;
+    GWeatherTemperature dew;
+    GWeatherWindDirection wind;
+    GWeatherWindSpeed windspeed;
+    GWeatherPressure pressure;
+    GWeatherVisibility visibility;
+    GWeatherUpdate sunrise;
+    GWeatherUpdate sunset;
+    GWeatherMoonPhase moonphase;
+    GWeatherMoonLatitude moonlatitude;
     gchar *forecast;
     GSList *forecast_list; /* list of WeatherInfo* for the forecast, NULL if not available */
     gchar *radar_buffer;
@@ -108,19 +127,8 @@ struct _WeatherInfo {
     GdkPixbufAnimation *radar;
     SoupSession *session;
     gint requests_pending;
-
-    WeatherInfoFunc finish_cb;
-    gpointer cb_data;
 };
 
-/*
- * Enum -> string conversions.
- */
-
-const gchar *	weather_wind_direction_string	(WeatherWindDirection wind);
-const gchar *	weather_sky_string		(WeatherSky sky);
-const gchar *	weather_conditions_string	(WeatherConditions cond);
-
 /* Values common to the parsing source files */
 
 #define DATA_SIZE			5000
@@ -165,17 +173,17 @@ const gchar *	weather_conditions_string	(WeatherConditions cond);
 #define SOL_PROGRESSION            (360./365.242191)
 #define PERIGEE_LONGITUDE(d)       (282.93768193 + (d)/36525.*0.32327364)
 
-void		metar_start_open	(WeatherInfo *info);
-void		iwin_start_open		(WeatherInfo *info);
-void		metoffice_start_open	(WeatherInfo *info);
-void		bom_start_open		(WeatherInfo *info);
-void		wx_start_open		(WeatherInfo *info);
+void		metar_start_open	(GWeatherInfo *info);
+void		iwin_start_open		(GWeatherInfo *info);
+void		metoffice_start_open	(GWeatherInfo *info);
+void		bom_start_open		(GWeatherInfo *info);
+void		wx_start_open		(GWeatherInfo *info);
 
 gboolean	metar_parse		(gchar *metar,
-					 WeatherInfo *info);
+					 GWeatherInfo *info);
 
-gboolean	requests_init		(WeatherInfo *info);
-void		request_done		(WeatherInfo *info,
+gboolean	requests_init		(GWeatherInfo *info);
+void		request_done		(GWeatherInfo *info,
 					 gboolean     ok);
 
 void		ecl2equ			(gdouble t,
@@ -184,12 +192,33 @@ void		ecl2equ			(gdouble t,
 					 gdouble *ra,
 					 gdouble *decl);
 gdouble		sunEclipLongitude	(time_t t);
-gboolean	calc_sun		(WeatherInfo *info);
-gboolean	calc_sun_time		(WeatherInfo *info, time_t t);
-gboolean	calc_moon		(WeatherInfo *info);
-gboolean	calc_moon_phases	(WeatherInfo *info, time_t *phases);
+gboolean	calc_sun		(GWeatherInfo *info);
+gboolean	calc_sun_time		(GWeatherInfo *info, time_t t);
+gboolean	calc_moon		(GWeatherInfo *info);
+gboolean	calc_moon_phases	(GWeatherInfo *info, time_t *phases);
+
+void		free_forecast_list	(GWeatherInfo *info);
 
-void		free_forecast_list	(WeatherInfo *info);
+GWeatherInfo   *_gweather_info_new_clone (GWeatherInfo *info);
+
+struct _GWeatherPrefs {
+    WeatherLocation *location;
+    gint update_interval;  /* in seconds */
+    gboolean update_enabled;
+    gboolean detailed;
+    gboolean radar_enabled;
+    gboolean use_custom_radar_url;
+    gchar *radar;
+
+    GWeatherTemperatureUnit temperature_unit;
+    gboolean use_temperature_default;
+    GWeatherSpeedUnit speed_unit;
+    gboolean use_speed_default;
+    GWeatherPressureUnit pressure_unit;
+    gboolean use_pressure_default;
+    GWeatherDistanceUnit distance_unit;
+    gboolean use_distance_default;
+};
 
 #endif /* __WEATHER_PRIV_H_ */
 
diff --git a/libgweather/weather-sun.c b/libgweather/weather-sun.c
index 42e4cb4..b0f299a 100644
--- a/libgweather/weather-sun.c
+++ b/libgweather/weather-sun.c
@@ -159,10 +159,11 @@ t0 (time_t date)
 
 
 static gboolean
-calc_sun2 (WeatherInfo *info, time_t t)
+calc_sun2 (GWeatherInfo *info, time_t t)
 {
-    gdouble obsLat = info->location->latitude;
-    gdouble obsLon = info->location->longitude;
+    GWeatherInfoPrivate *priv = info->priv;
+    gdouble obsLat = priv->location->latitude;
+    gdouble obsLon = priv->location->longitude;
     time_t gm_midn;
     time_t lcl_midn;
     gdouble gm_hoff, lambda;
@@ -175,8 +176,8 @@ calc_sun2 (WeatherInfo *info, time_t t)
     gdouble x, u, dt;
 
     /* Approximate preceding local midnight at observer's longitude */
-    obsLat = info->location->latitude;
-    obsLon = info->location->longitude;
+    obsLat = priv->location->latitude;
+    obsLon = priv->location->longitude;
     gm_midn = t - (t % 86400);
     gm_hoff = floor ((RADIANS_TO_DEGREES (obsLon) + 7.5) / 15.);
     lcl_midn = gm_midn - 3600. * gm_hoff;
@@ -202,12 +203,12 @@ calc_sun2 (WeatherInfo *info, time_t t)
      */
     decl_midn = MIN(decl1,decl2);
     decl_noon = (decl1+decl2)/2.;
-    info->midnightSun =
+    priv->midnightSun =
 	(obsLat > (M_PI/2.-decl_midn)) || (obsLat < (-M_PI/2.-decl_midn));
-    info->polarNight =
+    priv->polarNight =
 	(obsLat > (M_PI/2.+decl_noon)) || (obsLat < (-M_PI/2.+decl_noon));
-    if (info->midnightSun || info->polarNight) {
-	info->sunriseValid = info->sunsetValid = FALSE;
+    if (priv->midnightSun || priv->polarNight) {
+	priv->sunriseValid = priv->sunsetValid = FALSE;
 	return FALSE;
     }
 
@@ -220,7 +221,7 @@ calc_sun2 (WeatherInfo *info, time_t t)
 
     /* TODO: include calculations for regions near the poles. */
     if (isnan(rise1) || isnan(rise2)) {
-	info->sunriseValid = info->sunsetValid = FALSE;
+	priv->sunriseValid = priv->sunsetValid = FALSE;
         return FALSE;
     }
 
@@ -271,18 +272,18 @@ calc_sun2 (WeatherInfo *info, time_t t)
 	rise1 += 24;
     else if (rise1 >= 24.)
 	rise1 -= 24.;
-    info->sunriseValid = ((rise1 >= 0.) && (rise1 < 24.));
-    info->sunrise = (rise1 * 3600.) + lcl_midn;
+    priv->sunriseValid = ((rise1 >= 0.) && (rise1 < 24.));
+    priv->sunrise = (rise1 * 3600.) + lcl_midn;
 
     set1  = (set1 + dt - tt) * 0.9972695661;
     if (set1 < 0.)
 	set1 += 24;
     else if (set1 >= 24.)
 	set1 -= 24.;
-    info->sunsetValid = ((set1 >= 0.) && (set1 < 24.));
-    info->sunset = (set1 * 3600.) + lcl_midn;
+    priv->sunsetValid = ((set1 >= 0.) && (set1 < 24.));
+    priv->sunset = (set1 * 3600.) + lcl_midn;
 
-    return (info->sunriseValid || info->sunsetValid);
+    return (priv->sunriseValid || priv->sunsetValid);
 }
 
 
@@ -295,9 +296,9 @@ calc_sun2 (WeatherInfo *info, time_t t)
  * Returns: gboolean indicating if the results are valid.
  */
 gboolean
-calc_sun_time (WeatherInfo *info, time_t t)
+calc_sun_time (GWeatherInfo *info, time_t t)
 {
-    return info->location->latlon_valid && calc_sun2 (info, t);
+    return info->priv->location->coordinates != NULL && calc_sun2 (info, t);
 }
 
 /**
@@ -308,7 +309,7 @@ calc_sun_time (WeatherInfo *info, time_t t)
  * Returns: gboolean indicating if the results are valid.
  */
 gboolean
-calc_sun (WeatherInfo *info)
+calc_sun (GWeatherInfo *info)
 {
     return calc_sun_time(info, time(NULL));
 }
@@ -324,11 +325,14 @@ calc_sun (WeatherInfo *info)
  *  - next sunset, when icon changes to nighttime version
  */
 gint
-weather_info_next_sun_event (WeatherInfo *info)
+gweather_info_next_sun_event (GWeatherInfo *info)
 {
     time_t    now = time (NULL);
     struct tm ltm;
     time_t    nxtEvent;
+    GWeatherInfoPrivate *priv;
+
+    priv = info->priv;
 
     g_return_val_if_fail (info != NULL, -1);
 
@@ -343,11 +347,11 @@ weather_info_next_sun_event (WeatherInfo *info)
     ltm.tm_mday++;
     nxtEvent = mktime (&ltm);
 
-    if (info->sunsetValid &&
-	(info->sunset > now) && (info->sunset < nxtEvent))
-	nxtEvent = info->sunset;
-    if (info->sunriseValid &&
-	(info->sunrise > now) && (info->sunrise < nxtEvent))
-	nxtEvent = info->sunrise;
+    if (priv->sunsetValid &&
+	(priv->sunset > now) && (priv->sunset < nxtEvent))
+	nxtEvent = priv->sunset;
+    if (priv->sunriseValid &&
+	(priv->sunrise > now) && (priv->sunrise < nxtEvent))
+	nxtEvent = priv->sunrise;
     return (gint)(nxtEvent - now);
 }
diff --git a/libgweather/weather-wx.c b/libgweather/weather-wx.c
index 09002f2..67586d0 100644
--- a/libgweather/weather-wx.c
+++ b/libgweather/weather-wx.c
@@ -27,28 +27,30 @@
 static void
 wx_finish (SoupSession *session, SoupMessage *msg, gpointer data)
 {
-    WeatherInfo *info = (WeatherInfo *)data;
+    GWeatherInfo *info = (GWeatherInfo *)data;
+    GWeatherInfoPrivate *priv;
     GdkPixbufAnimation *animation;
 
     g_return_if_fail (info != NULL);
+    priv = info->priv;
 
     if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
 	g_warning ("Failed to get radar map image: %d %s.\n",
 		   msg->status_code, msg->reason_phrase);
-	g_object_unref (info->radar_loader);
+	g_object_unref (priv->radar_loader);
 	request_done (info, FALSE);
 	return;
     }
 
-    gdk_pixbuf_loader_close (info->radar_loader, NULL);
-    animation = gdk_pixbuf_loader_get_animation (info->radar_loader);
+    gdk_pixbuf_loader_close (priv->radar_loader, NULL);
+    animation = gdk_pixbuf_loader_get_animation (priv->radar_loader);
     if (animation != NULL) {
-	if (info->radar)
-	    g_object_unref (info->radar);
-	info->radar = animation;
-	g_object_ref (info->radar);
+	if (priv->radar)
+	    g_object_unref (priv->radar);
+	priv->radar = animation;
+	g_object_ref (priv->radar);
     }
-    g_object_unref (info->radar_loader);
+    g_object_unref (priv->radar_loader);
 
     request_done (info, TRUE);
 }
@@ -56,12 +58,12 @@ wx_finish (SoupSession *session, SoupMessage *msg, gpointer data)
 static void
 wx_got_chunk (SoupMessage *msg, SoupBuffer *chunk, gpointer data)
 {
-    WeatherInfo *info = (WeatherInfo *)data;
+    GWeatherInfo *info = (GWeatherInfo *)data;
     GError *error = NULL;
 
     g_return_if_fail (info != NULL);
 
-    gdk_pixbuf_loader_write (info->radar_loader, (guchar *)chunk->data,
+    gdk_pixbuf_loader_write (info->priv->radar_loader, (guchar *)chunk->data,
 			     chunk->length, &error);
     if (error) {
 	g_print ("%s \n", error->message);
@@ -71,20 +73,23 @@ wx_got_chunk (SoupMessage *msg, SoupBuffer *chunk, gpointer data)
 
 /* Get radar map and into newly allocated pixmap */
 void
-wx_start_open (WeatherInfo *info)
+wx_start_open (GWeatherInfo *info)
 {
     gchar *url;
     SoupMessage *msg;
     WeatherLocation *loc;
+    GWeatherInfoPrivate *priv;
 
     g_return_if_fail (info != NULL);
-    info->radar = NULL;
-    info->radar_loader = gdk_pixbuf_loader_new ();
-    loc = info->location;
+    priv = info->priv;
+
+    priv->radar = NULL;
+    priv->radar_loader = gdk_pixbuf_loader_new ();
+    loc = priv->location;
     g_return_if_fail (loc != NULL);
 
-    if (info->radar_url)
-	url = g_strdup (info->radar_url);
+    if (priv->radar_url)
+	url = g_strdup (priv->radar_url);
     else {
 	if (loc->radar[0] == '-')
 	    return;
@@ -100,8 +105,8 @@ wx_start_open (WeatherInfo *info)
 
     g_signal_connect (msg, "got-chunk", G_CALLBACK (wx_got_chunk), info);
     soup_message_body_set_accumulate (msg->response_body, FALSE);
-    soup_session_queue_message (info->session, msg, wx_finish, info);
+    soup_session_queue_message (priv->session, msg, wx_finish, info);
     g_free (url);
 
-    info->requests_pending++;
+    priv->requests_pending++;
 }
diff --git a/libgweather/weather.c b/libgweather/weather.c
index f574591..953f490 100644
--- a/libgweather/weather.c
+++ b/libgweather/weather.c
@@ -40,6 +40,8 @@
 #define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
 #include "weather.h"
 #include "weather-priv.h"
+#include "gweather-prefs.h"
+#include "gweather-enum-types.h"
 
 #define MOON_PHASES 36
 
@@ -52,6 +54,22 @@
 
 static void _weather_internal_check (void);
 
+enum {
+    PROP_0,
+    PROP_LOCATION,
+    PROP_TYPE,
+    PROP_PREFS,
+    PROP_LAST
+};
+
+enum {
+    SIGNAL_UPDATED,
+    SIGNAL_LAST
+};
+
+static guint gweather_info_signals[SIGNAL_LAST];
+
+G_DEFINE_TYPE (GWeatherInfo, gweather_info, G_TYPE_OBJECT);
 
 static inline void
 gweather_gettext_init (void)
@@ -121,41 +139,28 @@ dmsh2rad (const gchar *latlon)
 }
 
 WeatherLocation *
-weather_location_new (const gchar *name, const gchar *code,
-		      const gchar *zone, const gchar *radar,
-		      const gchar *coordinates,
-		      const gchar *country_code,
-		      const gchar *tz_hint)
+_weather_location_new (const gchar *name, const gchar *code,
+		       const gchar *zone, const gchar *radar,
+		       const gchar *coordinates,
+		       const gchar *country_code,
+		       const gchar *tz_hint)
 {
     WeatherLocation *location;
 
     _weather_internal_check ();
 
-    location = g_new (WeatherLocation, 1);
+    location = g_slice_new0 (WeatherLocation);
 
     /* name and metar code must be set */
     location->name = g_strdup (name);
     location->code = g_strdup (code);
 
-    if (zone) {
+    if (zone)
         location->zone = g_strdup (zone);
-    } else {
-        location->zone = g_strdup ("------");
-    }
 
-    if (radar) {
+    if (radar)
         location->radar = g_strdup (radar);
-    } else {
-        location->radar = g_strdup ("---");
-    }
 
-    if (location->zone[0] == '-') {
-        location->zone_valid = FALSE;
-    } else {
-        location->zone_valid = TRUE;
-    }
-
-    location->coordinates = NULL;
     if (coordinates)
     {
 	char **pieces;
@@ -174,13 +179,10 @@ weather_location_new (const gchar *name, const gchar *code,
 
     if (!location->coordinates)
     {
-        location->coordinates = g_strdup ("---");
         location->latitude = DBL_MAX;
         location->longitude = DBL_MAX;
     }
 
-    location->latlon_valid = (location->latitude < DBL_MAX && location->longitude < DBL_MAX);
-
     location->country_code = g_strdup (country_code);
     location->tz_hint = g_strdup (tz_hint);
 
@@ -188,24 +190,38 @@ weather_location_new (const gchar *name, const gchar *code,
 }
 
 WeatherLocation *
-weather_location_clone (const WeatherLocation *location)
+_weather_location_clone (const WeatherLocation *location)
 {
     WeatherLocation *clone;
 
     g_return_val_if_fail (location != NULL, NULL);
 
-    clone = weather_location_new (location->name,
-				  location->code, location->zone,
-				  location->radar, location->coordinates,
-				  location->country_code, location->tz_hint);
-    clone->latitude = location->latitude;
-    clone->longitude = location->longitude;
-    clone->latlon_valid = location->latlon_valid;
+    clone = g_slice_new0 (WeatherLocation);
+
+    clone->name = g_strdup (location->name);
+    clone->country_code = g_strdup (location->country_code);
+    clone->tz_hint = g_strdup (location->tz_hint);
+
+    if (location->zone)
+	clone->zone = g_strdup (location->zone);
+
+    if (location->radar)
+	clone->radar = g_strdup (location->radar);
+
+    if (location->coordinates) {
+	clone->coordinates = g_strdup (location->coordinates);
+	clone->latitude = location->latitude;
+	clone->longitude = location->longitude;
+    } else {
+	clone->latitude = DBL_MAX;
+	clone->longitude = DBL_MAX;
+    }
+
     return clone;
 }
 
 void
-weather_location_free (WeatherLocation *location)
+_weather_location_free (WeatherLocation *location)
 {
     if (location) {
         g_free (location->name);
@@ -216,12 +232,12 @@ weather_location_free (WeatherLocation *location)
         g_free (location->country_code);
         g_free (location->tz_hint);
 
-        g_free (location);
+        g_slice_free (WeatherLocation, location);
     }
 }
 
 gboolean
-weather_location_equal (const WeatherLocation *location1, const WeatherLocation *location2)
+_weather_location_equal (const WeatherLocation *location1, const WeatherLocation *location2)
 {
     /* if something is NULL, then it's TRUE if and only if both are NULL) */
     if (location1 == NULL || location2 == NULL)
@@ -244,7 +260,7 @@ static const gchar *wind_direction_str[] = {
 };
 
 const gchar *
-weather_wind_direction_string (WeatherWindDirection wind)
+gweather_wind_direction_to_string (GWeatherWindDirection wind)
 {
     if (wind <= WIND_INVALID || wind >= WIND_LAST)
 	return _("Invalid");
@@ -261,7 +277,7 @@ static const gchar *sky_str[] = {
 };
 
 const gchar *
-weather_sky_string (WeatherSky sky)
+gweather_sky_to_string (GWeatherSky sky)
 {
     if (sky <= SKY_INVALID || sky >= SKY_LAST)
 	return _("Invalid");
@@ -323,18 +339,18 @@ static const gchar *conditions_str[24][13] = {
 };
 
 const gchar *
-weather_conditions_string (WeatherConditions cond)
+gweather_conditions_to_string (GWeatherConditions *cond)
 {
     const gchar *str;
 
-    if (!cond.significant) {
+    if (!cond->significant) {
 	return "-";
     } else {
-	if (cond.phenomenon > PHENOMENON_INVALID &&
-	    cond.phenomenon < PHENOMENON_LAST &&
-	    cond.qualifier > QUALIFIER_INVALID &&
-	    cond.qualifier < QUALIFIER_LAST)
-	    str = _(conditions_str[(int)cond.phenomenon][(int)cond.qualifier]);
+	if (cond->phenomenon > PHENOMENON_INVALID &&
+	    cond->phenomenon < PHENOMENON_LAST &&
+	    cond->qualifier > QUALIFIER_INVALID &&
+	    cond->qualifier < QUALIFIER_LAST)
+	    str = _(conditions_str[(int)cond->phenomenon][(int)cond->qualifier]);
 	else
 	    str = _("Invalid");
 	return (strlen (str) > 0) ? str : "-";
@@ -345,40 +361,33 @@ weather_conditions_string (WeatherConditions cond)
 
 
 gboolean
-requests_init (WeatherInfo *info)
+requests_init (GWeatherInfo *info)
 {
-    if (info->requests_pending)
+    if (info->priv->requests_pending)
         return FALSE;
 
     return TRUE;
 }
 
-void request_done (WeatherInfo *info, gboolean ok)
+void request_done (GWeatherInfo *info, gboolean ok)
 {
     if (ok) {
 	(void) calc_sun (info);
-	info->moonValid = info->valid && calc_moon (info);
+	info->priv->moonValid = info->priv->valid && calc_moon (info);
     }
-    if (!--info->requests_pending)
-        info->finish_cb (info, info->cb_data);
+    if (!--info->priv->requests_pending)
+        g_signal_emit (info, gweather_info_signals[SIGNAL_UPDATED], 0);
 }
 
 /* it's OK to pass in NULL */
 void
-free_forecast_list (WeatherInfo *info)
+free_forecast_list (GWeatherInfo *info)
 {
-    GSList *p;
-
     if (!info)
 	return;
 
-    for (p = info->forecast_list; p; p = p->next)
-	weather_info_free (p->data);
-
-    if (info->forecast_list) {
-	g_slist_free (info->forecast_list);
-	info->forecast_list = NULL;
-    }
+    g_slist_free_full (info->priv->forecast_list, g_object_unref);
+    info->priv->forecast_list = NULL;
 }
 
 /* Relative humidity computation - thanks to <Olof Oberg modopaper modogroup com> */
@@ -402,11 +411,12 @@ calc_humidity (gdouble temp, gdouble dewp)
 }
 
 static inline gdouble
-calc_apparent (WeatherInfo *info)
+calc_apparent (GWeatherInfo *info)
 {
-    gdouble temp = info->temp;
-    gdouble wind = WINDSPEED_KNOTS_TO_MPH (info->windspeed);
+    gdouble temp = info->priv->temp;
+    gdouble wind = WINDSPEED_KNOTS_TO_MPH (info->priv->windspeed);
     gdouble apparent = -1000.;
+    gdouble dew = info->priv->dew;
 
     /*
      * Wind chill calculations as of 01-Nov-2001
@@ -427,8 +437,8 @@ calc_apparent (WeatherInfo *info)
      * http://www.srh.noaa.gov/fwd/heatindex/heat5.html
      */
     else if (temp >= 80.0) {
-        if (info->temp >= -500. && info->dew >= -500.) {
-	    gdouble humidity = calc_humidity (info->temp, info->dew);
+        if (temp >= -500. && dew >= -500.) {
+	    gdouble humidity = calc_humidity (temp, dew);
 	    gdouble t2 = temp * temp;
 	    gdouble h2 = humidity * humidity;
 
@@ -480,237 +490,224 @@ calc_apparent (WeatherInfo *info)
     return apparent;
 }
 
-WeatherInfo *
-_weather_info_fill (WeatherInfo *info,
-		    WeatherLocation *location,
-		    const WeatherPrefs *prefs,
-		    WeatherInfoFunc cb,
-		    gpointer data)
+static void
+gweather_info_reset (GWeatherInfo *info)
 {
-    g_return_val_if_fail (((info == NULL) && (location != NULL)) || \
-			  ((info != NULL) && (location == NULL)), NULL);
-    g_return_val_if_fail (prefs != NULL, NULL);
-
-    /* FIXME: i'm not sure this works as intended anymore */
-    if (!info) {
-    	info = g_new0 (WeatherInfo, 1);
-    	info->requests_pending = 0;
-    	info->location = weather_location_clone (location);
-    } else {
-        location = info->location;
-	if (info->forecast)
-	    g_free (info->forecast);
-	info->forecast = NULL;
+    GWeatherInfoPrivate *priv = info->priv;
 
-	free_forecast_list (info);
+    if (priv->forecast)
+	g_free (priv->forecast);
+    priv->forecast = NULL;
 
-	if (info->radar != NULL) {
-	    g_object_unref (info->radar);
-	    info->radar = NULL;
-	}
-    }
-
-    /* Update in progress */
-    if (!requests_init (info)) {
-        return NULL;
-    }
+    free_forecast_list (info);
 
-    /* Defaults (just in case...) */
-    /* Well, no just in case anymore.  We may actually fail to fetch some
-     * fields. */
-    info->forecast_type = prefs->type;
-
-    info->temperature_unit = prefs->temperature_unit;
-    info->speed_unit = prefs->speed_unit;
-    info->pressure_unit = prefs->pressure_unit;
-    info->distance_unit = prefs->distance_unit;
-
-    info->update = 0;
-    info->sky = -1;
-    info->cond.significant = FALSE;
-    info->cond.phenomenon = PHENOMENON_NONE;
-    info->cond.qualifier = QUALIFIER_NONE;
-    info->temp = -1000.0;
-    info->tempMinMaxValid = FALSE;
-    info->temp_min = -1000.0;
-    info->temp_max = -1000.0;
-    info->dew = -1000.0;
-    info->wind = -1;
-    info->windspeed = -1;
-    info->pressure = -1.0;
-    info->visibility = -1.0;
-    info->sunriseValid = FALSE;
-    info->sunsetValid = FALSE;
-    info->moonValid = FALSE;
-    info->sunrise = 0;
-    info->sunset = 0;
-    info->moonphase = 0;
-    info->moonlatitude = 0;
-    info->forecast = NULL;
-    info->forecast_list = NULL;
-    info->radar = NULL;
-    info->radar_url = prefs->radar && prefs->radar_custom_url ?
-    		      g_strdup (prefs->radar_custom_url) : NULL;
-    info->finish_cb = cb;
-    info->cb_data = data;
-
-    if (!info->session) {
-	info->session = soup_session_async_new ();
-#ifdef HAVE_LIBSOUP_GNOME
-	soup_session_add_feature_by_type (info->session, SOUP_TYPE_PROXY_RESOLVER_GNOME);
-#endif
+    if (priv->radar != NULL) {
+	g_object_unref (priv->radar);
+	priv->radar = NULL;
     }
 
-    metar_start_open (info);
-    iwin_start_open (info);
-
-    if (prefs->radar) {
-        wx_start_open (info);
-    }
-
-    return info;
+    priv->update = 0;
+    priv->sky = -1;
+    priv->cond.significant = FALSE;
+    priv->cond.phenomenon = PHENOMENON_NONE;
+    priv->cond.qualifier = QUALIFIER_NONE;
+    priv->temp = -1000.0;
+    priv->tempMinMaxValid = FALSE;
+    priv->temp_min = -1000.0;
+    priv->temp_max = -1000.0;
+    priv->dew = -1000.0;
+    priv->wind = -1;
+    priv->windspeed = -1;
+    priv->pressure = -1.0;
+    priv->visibility = -1.0;
+    priv->sunriseValid = FALSE;
+    priv->sunsetValid = FALSE;
+    priv->moonValid = FALSE;
+    priv->sunrise = 0;
+    priv->sunset = 0;
+    priv->moonphase = 0;
+    priv->moonlatitude = 0;
+    priv->forecast = NULL;
+    priv->forecast_list = NULL;
+    priv->radar = NULL;
 }
 
 void
-weather_info_abort (WeatherInfo *info)
+gweather_info_init (GWeatherInfo *info)
 {
-    g_return_if_fail (info != NULL);
+    info->priv = G_TYPE_INSTANCE_GET_PRIVATE (info, GWEATHER_TYPE_INFO, GWeatherInfoPrivate);
 
-    if (info->session) {
-	soup_session_abort (info->session);
-	info->requests_pending = 0;
-    }
+    gweather_info_reset (info);
 }
 
-WeatherInfo *
-weather_info_clone (const WeatherInfo *info)
+void
+gweather_info_set_preferences (GWeatherInfo        *info,
+			       const GWeatherPrefs *prefs)
 {
-    WeatherInfo *clone;
+    GWeatherInfoPrivate *priv;
 
-    g_return_val_if_fail (info != NULL, NULL);
+    g_return_if_fail (GWEATHER_IS_INFO (info));
+    g_return_if_fail (prefs != NULL);
 
-    clone = g_new (WeatherInfo, 1);
+    priv = info->priv;
 
+    priv->temperature_unit = prefs->temperature_unit;
+    priv->speed_unit = prefs->speed_unit;
+    priv->pressure_unit = prefs->pressure_unit;
+    priv->distance_unit = prefs->distance_unit;
 
-    /* move everything */
-    g_memmove (clone, info, sizeof (WeatherInfo));
+    g_free (priv->radar_url);
+    priv->radar_url = prefs->use_custom_radar_url && prefs->radar ?
+	              g_strdup (prefs->radar) : NULL;
 
+    if (!priv->location)
+	priv->location = _weather_location_clone (prefs->location);
+}
 
-    /* special moves */
-    clone->location = weather_location_clone (info->location);
-    /* This handles null correctly */
-    clone->forecast = g_strdup (info->forecast);
-    clone->radar_url = g_strdup (info->radar_url);
+void
+gweather_info_update (GWeatherInfo *info)
+{
+    GWeatherInfoPrivate *priv = info->priv;
 
-    if (info->forecast_list) {
-	GSList *p;
+    /* Update in progress */
+    if (!requests_init (info))
+        return ;
 
-	clone->forecast_list = NULL;
-	for (p = info->forecast_list; p; p = p->next) {
-	    clone->forecast_list = g_slist_prepend (clone->forecast_list, weather_info_clone (p->data));
-	}
+    gweather_info_reset (info);
 
-	clone->forecast_list = g_slist_reverse (clone->forecast_list);
+    if (!priv->session) {
+	priv->session = soup_session_async_new ();
+#ifdef HAVE_LIBSOUP_GNOME
+	soup_session_add_feature_by_type (priv->session, SOUP_TYPE_PROXY_RESOLVER_GNOME);
+#endif
     }
 
-    clone->radar = info->radar;
-    if (clone->radar != NULL)
-	g_object_ref (clone->radar);
+    metar_start_open (info);
+    iwin_start_open (info);
 
-    return clone;
+    if (priv->radar) {
+        wx_start_open (info);
+    }
 }
 
 void
-weather_info_free (WeatherInfo *info)
+gweather_info_abort (GWeatherInfo *info)
 {
-    if (!info)
-        return;
+    g_return_if_fail (GWEATHER_IS_INFO (info));
+
+    if (info->priv->session) {
+	soup_session_abort (info->priv->session);
+	info->priv->requests_pending = 0;
+    }
+}
 
-    weather_info_abort (info);
-    if (info->session)
-	g_object_unref (info->session);
+static void
+gweather_info_finalize (GObject *object)
+{
+    GWeatherInfo *info = GWEATHER_INFO (object);
+    GWeatherInfoPrivate *priv = info->priv;
+
+    gweather_info_abort (info);
+    if (priv->session)
+	g_object_unref (priv->session);
+
+    _weather_location_free (priv->location);
+    priv->location = NULL;
+
+    if (priv->glocation) {
+	gweather_location_unref (priv->glocation);
+	priv->glocation = NULL;
+    }
 
-    weather_location_free (info->location);
-    info->location = NULL;
+    g_free (priv->forecast);
+    priv->forecast = NULL;
 
-    g_free (info->forecast);
-    info->forecast = NULL;
+    g_free (priv->radar_url);
+    priv->radar_url = NULL;
 
     free_forecast_list (info);
 
-    if (info->radar != NULL) {
-        g_object_unref (info->radar);
-        info->radar = NULL;
+    if (priv->radar != NULL) {
+        g_object_unref (priv->radar);
+        priv->radar = NULL;
     }
-	
-    g_free (info);
+
+    G_OBJECT_GET_CLASS (gweather_info_parent_class)->finalize (object);
 }
 
 gboolean
-weather_info_is_valid (WeatherInfo *info)
+gweather_info_is_valid (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
-    return info->valid;
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
+    return info->priv->valid;
 }
 
 gboolean
-weather_info_network_error (WeatherInfo *info)
+gweather_info_network_error (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
-    return info->network_error;
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
+    return info->priv->network_error;
 }
 
 void
-weather_info_to_metric (WeatherInfo *info)
+gweather_info_to_metric (GWeatherInfo *info)
 {
-    g_return_if_fail (info != NULL);
+    GWeatherInfoPrivate *priv;
 
-    info->temperature_unit = TEMP_UNIT_CENTIGRADE;
-    info->speed_unit = SPEED_UNIT_MS;
-    info->pressure_unit = PRESSURE_UNIT_HPA;
-    info->distance_unit = DISTANCE_UNIT_METERS;
+    g_return_if_fail (GWEATHER_IS_INFO (info));
+    priv = info->priv;
+
+    priv->temperature_unit = TEMP_UNIT_CENTIGRADE;
+    priv->speed_unit = SPEED_UNIT_MS;
+    priv->pressure_unit = PRESSURE_UNIT_HPA;
+    priv->distance_unit = DISTANCE_UNIT_METERS;
 }
 
 void
-weather_info_to_imperial (WeatherInfo *info)
+gweather_info_to_imperial (GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv;
+
     g_return_if_fail (info != NULL);
+    priv = info->priv;
 
-    info->temperature_unit = TEMP_UNIT_FAHRENHEIT;
-    info->speed_unit = SPEED_UNIT_MPH;
-    info->pressure_unit = PRESSURE_UNIT_INCH_HG;
-    info->distance_unit = DISTANCE_UNIT_MILES;
+    priv->temperature_unit = TEMP_UNIT_FAHRENHEIT;
+    priv->speed_unit = SPEED_UNIT_MPH;
+    priv->pressure_unit = PRESSURE_UNIT_INCH_HG;
+    priv->distance_unit = DISTANCE_UNIT_MILES;
 }
 
-const WeatherLocation *
-weather_info_get_location (WeatherInfo *info)
+const GWeatherLocation *
+gweather_info_get_location (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, NULL);
-    return info->location;
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
+    return info->priv->glocation;
 }
 
 const gchar *
-weather_info_get_location_name (WeatherInfo *info)
+gweather_info_get_location_name (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, NULL);
-    g_return_val_if_fail (info->location != NULL, NULL);
-    return info->location->name;
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
+
+    if (!info->priv->location)
+	return NULL;
+    return info->priv->location->name;
 }
 
 const gchar *
-weather_info_get_update (WeatherInfo *info)
+gweather_info_get_update (GWeatherInfo *info)
 {
     static gchar buf[200];
     char *utf8, *timeformat;
 
-    g_return_val_if_fail (info != NULL, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
 
-    if (!info->valid)
+    if (!info->priv->valid)
         return "-";
 
-    if (info->update != 0) {
+    if (info->priv->update != 0) {
         struct tm tm;
-        localtime_r (&info->update, &tm);
+        localtime_r (&info->priv->update, &tm);
 	/* TRANSLATOR: this is a format string for strftime
 	 *             see `man 3 strftime` for more details
 	 */
@@ -737,27 +734,27 @@ weather_info_get_update (WeatherInfo *info)
 }
 
 const gchar *
-weather_info_get_sky (WeatherInfo *info)
+gweather_info_get_sky (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, NULL);
-    if (!info->valid)
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
+    if (!info->priv->valid)
         return "-";
-    if (info->sky < 0)
+    if (info->priv->sky < 0)
 	return _("Unknown");
-    return weather_sky_string (info->sky);
+    return gweather_sky_to_string (info->priv->sky);
 }
 
 const gchar *
-weather_info_get_conditions (WeatherInfo *info)
+gweather_info_get_conditions (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, NULL);
-    if (!info->valid)
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
+    if (!info->priv->valid)
         return "-";
-    return weather_conditions_string (info->cond);
+    return gweather_conditions_to_string (&info->priv->cond);
 }
 
 static const gchar *
-temperature_string (gfloat temp_f, TempUnit to_unit, gboolean want_round)
+temperature_string (gfloat temp_f, GWeatherTemperatureUnit to_unit, gboolean want_round)
 {
     static gchar buf[100];
 
@@ -801,69 +798,71 @@ temperature_string (gfloat temp_f, TempUnit to_unit, gboolean want_round)
 }
 
 const gchar *
-weather_info_get_temp (WeatherInfo *info)
+gweather_info_get_temp (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
 
-    if (!info->valid)
+    if (!info->priv->valid)
         return "-";
-    if (info->temp < -500.0)
+    if (info->priv->temp < -500.0)
         return _("Unknown");
 
-    return temperature_string (info->temp, info->temperature_unit, FALSE);
+    return temperature_string (info->priv->temp, info->priv->temperature_unit, FALSE);
 }
 
 const gchar *
-weather_info_get_temp_min (WeatherInfo *info)
+gweather_info_get_temp_min (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
 
-    if (!info->valid || !info->tempMinMaxValid)
+    if (!info->priv->valid || !info->priv->tempMinMaxValid)
         return "-";
-    if (info->temp_min < -500.0)
+    if (info->priv->temp_min < -500.0)
         return _("Unknown");
 
-    return temperature_string (info->temp_min, info->temperature_unit, FALSE);
+    return temperature_string (info->priv->temp_min, info->priv->temperature_unit, FALSE);
 }
 
 const gchar *
-weather_info_get_temp_max (WeatherInfo *info)
+gweather_info_get_temp_max (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
 
-    if (!info->valid || !info->tempMinMaxValid)
+    if (!info->priv->valid || !info->priv->tempMinMaxValid)
         return "-";
-    if (info->temp_max < -500.0)
+    if (info->priv->temp_max < -500.0)
         return _("Unknown");
 
-    return temperature_string (info->temp_max, info->temperature_unit, FALSE);
+    return temperature_string (info->priv->temp_max, info->priv->temperature_unit, FALSE);
 }
 
 const gchar *
-weather_info_get_dew (WeatherInfo *info)
+gweather_info_get_dew (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
 
-    if (!info->valid)
+    if (!info->priv->valid)
         return "-";
-    if (info->dew < -500.0)
+    if (info->priv->dew < -500.0)
         return _("Unknown");
 
-    return temperature_string (info->dew, info->temperature_unit, FALSE);
+    return temperature_string (info->priv->dew, info->priv->temperature_unit, FALSE);
 }
 
 const gchar *
-weather_info_get_humidity (WeatherInfo *info)
+gweather_info_get_humidity (GWeatherInfo *info)
 {
+    /* FIXME: a static buffer, exposed outside the function? omg! */
+
     static gchar buf[20];
     gdouble humidity;
 
-    g_return_val_if_fail (info != NULL, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
 
-    if (!info->valid)
+    if (!info->priv->valid)
         return "-";
 
-    humidity = calc_humidity (info->temp, info->dew);
+    humidity = calc_humidity (info->priv->temp, info->priv->dew);
     if (humidity < 0.0)
         return _("Unknown");
 
@@ -873,23 +872,23 @@ weather_info_get_humidity (WeatherInfo *info)
 }
 
 const gchar *
-weather_info_get_apparent (WeatherInfo *info)
+gweather_info_get_apparent (GWeatherInfo *info)
 {
     gdouble apparent;
 
-    g_return_val_if_fail (info != NULL, NULL);
-    if (!info->valid)
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
+    if (!info->priv->valid)
         return "-";
 
     apparent = calc_apparent (info);
     if (apparent < -500.0)
         return _("Unknown");
 
-    return temperature_string (apparent, info->temperature_unit, FALSE);
+    return temperature_string (apparent, info->priv->temperature_unit, FALSE);
 }
 
 static const gchar *
-windspeed_string (gfloat knots, SpeedUnit to_unit)
+windspeed_string (gfloat knots, GWeatherSpeedUnit to_unit)
 {
     static gchar buf[100];
 
@@ -928,70 +927,76 @@ windspeed_string (gfloat knots, SpeedUnit to_unit)
 }
 
 const gchar *
-weather_info_get_wind (WeatherInfo *info)
+gweather_info_get_wind (GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv;
     static gchar buf[200];
 
-    g_return_val_if_fail (info != NULL, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
 
-    if (!info->valid)
+    priv = info->priv;
+
+    if (!priv->valid)
         return "-";
-    if (info->windspeed < 0.0 || info->wind < 0)
+    if (priv->windspeed < 0.0 || priv->wind < 0)
         return _("Unknown");
-    if (info->windspeed == 0.00) {
+    if (priv->windspeed == 0.00) {
         strncpy (buf, _("Calm"), sizeof (buf));
 	buf[sizeof (buf)-1] = '\0';
     } else {
         /* TRANSLATOR: This is 'wind direction' / 'wind speed' */
         g_snprintf (buf, sizeof (buf), _("%s / %s"),
-		    weather_wind_direction_string (info->wind),
-		    windspeed_string (info->windspeed, info->speed_unit));
+		    gweather_wind_direction_to_string (priv->wind),
+		    windspeed_string (priv->windspeed, priv->speed_unit));
     }
     return buf;
 }
 
 const gchar *
-weather_info_get_pressure (WeatherInfo *info)
+gweather_info_get_pressure (GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv;
     static gchar buf[100];
 
-    g_return_val_if_fail (info != NULL, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
+
+    priv = info->priv;
 
-    if (!info->valid)
+    if (!priv->valid)
         return "-";
-    if (info->pressure < 0.0)
+    if (priv->pressure < 0.0)
         return _("Unknown");
 
-    switch (info->pressure_unit) {
+    switch (priv->pressure_unit) {
     case PRESSURE_UNIT_INCH_HG:
 	/* TRANSLATOR: This is pressure in inches of mercury */
-	g_snprintf (buf, sizeof (buf), _("%.2f inHg"), info->pressure);
+	g_snprintf (buf, sizeof (buf), _("%.2f inHg"), priv->pressure);
 	break;
     case PRESSURE_UNIT_MM_HG:
 	/* TRANSLATOR: This is pressure in millimeters of mercury */
-	g_snprintf (buf, sizeof (buf), _("%.1f mmHg"), PRESSURE_INCH_TO_MM (info->pressure));
+	g_snprintf (buf, sizeof (buf), _("%.1f mmHg"), PRESSURE_INCH_TO_MM (priv->pressure));
 	break;
     case PRESSURE_UNIT_KPA:
 	/* TRANSLATOR: This is pressure in kiloPascals */
-	g_snprintf (buf, sizeof (buf), _("%.2f kPa"), PRESSURE_INCH_TO_KPA (info->pressure));
+	g_snprintf (buf, sizeof (buf), _("%.2f kPa"), PRESSURE_INCH_TO_KPA (priv->pressure));
 	break;
     case PRESSURE_UNIT_HPA:
 	/* TRANSLATOR: This is pressure in hectoPascals */
-	g_snprintf (buf, sizeof (buf), _("%.2f hPa"), PRESSURE_INCH_TO_HPA (info->pressure));
+	g_snprintf (buf, sizeof (buf), _("%.2f hPa"), PRESSURE_INCH_TO_HPA (priv->pressure));
 	break;
     case PRESSURE_UNIT_MB:
 	/* TRANSLATOR: This is pressure in millibars */
-	g_snprintf (buf, sizeof (buf), _("%.2f mb"), PRESSURE_INCH_TO_MB (info->pressure));
+	g_snprintf (buf, sizeof (buf), _("%.2f mb"), PRESSURE_INCH_TO_MB (priv->pressure));
 	break;
     case PRESSURE_UNIT_ATM:
 	/* TRANSLATOR: This is pressure in atmospheres */
-	g_snprintf (buf, sizeof (buf), _("%.3f atm"), PRESSURE_INCH_TO_ATM (info->pressure));
+	g_snprintf (buf, sizeof (buf), _("%.3f atm"), PRESSURE_INCH_TO_ATM (priv->pressure));
 	break;
 
     case PRESSURE_UNIT_INVALID:
     case PRESSURE_UNIT_DEFAULT:
     default:
-	g_warning ("Conversion to illegal pressure unit: %d", info->pressure_unit);
+	g_warning ("Conversion to illegal pressure unit: %d", priv->pressure_unit);
 	return _("Unknown");
     }
 
@@ -999,35 +1004,38 @@ weather_info_get_pressure (WeatherInfo *info)
 }
 
 const gchar *
-weather_info_get_visibility (WeatherInfo *info)
+gweather_info_get_visibility (GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv;
     static gchar buf[100];
 
-    g_return_val_if_fail (info != NULL, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
 
-    if (!info->valid)
+    priv = info->priv;
+
+    if (!priv->valid)
         return "-";
-    if (info->visibility < 0.0)
+    if (priv->visibility < 0.0)
         return _("Unknown");
 
-    switch (info->distance_unit) {
+    switch (priv->distance_unit) {
     case DISTANCE_UNIT_MILES:
 	/* TRANSLATOR: This is the visibility in miles */
-	g_snprintf (buf, sizeof (buf), _("%.1f miles"), info->visibility);
+	g_snprintf (buf, sizeof (buf), _("%.1f miles"), priv->visibility);
 	break;
     case DISTANCE_UNIT_KM:
 	/* TRANSLATOR: This is the visibility in kilometers */
-	g_snprintf (buf, sizeof (buf), _("%.1f km"), VISIBILITY_SM_TO_KM (info->visibility));
+	g_snprintf (buf, sizeof (buf), _("%.1f km"), VISIBILITY_SM_TO_KM (priv->visibility));
 	break;
     case DISTANCE_UNIT_METERS:
 	/* TRANSLATOR: This is the visibility in meters */
-	g_snprintf (buf, sizeof (buf), _("%.0fm"), VISIBILITY_SM_TO_M (info->visibility));
+	g_snprintf (buf, sizeof (buf), _("%.0fm"), VISIBILITY_SM_TO_M (priv->visibility));
 	break;
 
     case DISTANCE_UNIT_INVALID:
     case DISTANCE_UNIT_DEFAULT:
     default:
-	g_warning ("Conversion to illegal visibility unit: %d", info->pressure_unit);
+	g_warning ("Conversion to illegal visibility unit: %d", priv->pressure_unit);
 	return _("Unknown");
     }
 
@@ -1035,57 +1043,68 @@ weather_info_get_visibility (WeatherInfo *info)
 }
 
 const gchar *
-weather_info_get_sunrise (WeatherInfo *info)
+gweather_info_get_sunrise (GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv;
     static gchar buf[200];
     struct tm tm;
 
-    g_return_val_if_fail (info && info->location, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
+    g_return_val_if_fail (info->priv->location, NULL);
+
+    priv = info->priv;
 
-    if (!info->location->latlon_valid)
+    if (!priv->location->coordinates)
         return "-";
-    if (!info->valid)
+    if (!priv->valid)
         return "-";
     if (!calc_sun (info))
         return "-";
 
-    localtime_r (&info->sunrise, &tm);
+    localtime_r (&priv->sunrise, &tm);
     if (strftime (buf, sizeof (buf), _("%H:%M"), &tm) <= 0)
         return "-";
     return buf;
 }
 
 const gchar *
-weather_info_get_sunset (WeatherInfo *info)
+gweather_info_get_sunset (GWeatherInfo *info)
 {
+    GWeatherInfoPrivate *priv;
     static gchar buf[200];
     struct tm tm;
 
-    g_return_val_if_fail (info && info->location, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
+    g_return_val_if_fail (info->priv->location, NULL);
+
+    priv = info->priv;
 
-    if (!info->location->latlon_valid)
+    if (!priv->location->coordinates)
         return "-";
-    if (!info->valid)
+    if (!priv->valid)
         return "-";
     if (!calc_sun (info))
         return "-";
 
-    localtime_r (&info->sunset, &tm);
+    localtime_r (&priv->sunset, &tm);
     if (strftime (buf, sizeof (buf), _("%H:%M"), &tm) <= 0)
         return "-";
     return buf;
 }
 
 const gchar *
-weather_info_get_forecast (WeatherInfo *info)
+gweather_info_get_forecast (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, NULL);
-    return info->forecast;
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
+    return info->priv->forecast;
 }
 
 /**
- * weather_info_get_forecast_list:
- * Returns list of WeatherInfo* objects for the forecast.
+ * gweather_info_get_forecast_list:
+ * @info: a #GWeatherInfo
+ *
+ * Returns: (transfer none) (element-type GWeather.Info): list
+ * of GWeatherInfo* objects for the forecast.
  * The list is owned by the 'info' object thus is alive as long
  * as the 'info'. This list is filled only when requested with
  * type FORECAST_LIST and if available for given location.
@@ -1093,70 +1112,88 @@ weather_info_get_forecast (WeatherInfo *info)
  * is used for.
  **/
 GSList *
-weather_info_get_forecast_list (WeatherInfo *info)
+gweather_info_get_forecast_list (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
 
-    if (!info->valid)
+    if (!info->priv->valid)
 	return NULL;
 
-    return info->forecast_list;
+    return info->priv->forecast_list;
 }
 
+/**
+ * gweather_info_get_radar:
+ * @info: a #GWeatherInfo
+ *
+ * Returns: (transfer none): what?
+ */
 GdkPixbufAnimation *
-weather_info_get_radar (WeatherInfo *info)
+gweather_info_get_radar (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, NULL);
-    return info->radar;
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
+    return info->priv->radar;
 }
 
 const gchar *
-weather_info_get_temp_summary (WeatherInfo *info)
+gweather_info_get_temp_summary (GWeatherInfo *info)
 {
-    g_return_val_if_fail (info != NULL, NULL);
+    GWeatherInfoPrivate *priv;
 
-    if (!info->valid || info->temp < -500.0)
-        return "--";
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
 
-    return temperature_string (info->temp, info->temperature_unit, TRUE);
+    priv = info->priv;
+
+    if (!priv->valid || priv->temp < -500.0)
+        return "--";
 
+    return temperature_string (priv->temp, priv->temperature_unit, TRUE);
 }
 
+/**
+ * gweather_info_get_weather_summary:
+ * @info: a #GWeatherInfo
+ *
+ * Returns: (transfer full): a summary for current weather conditions.
+ */
 gchar *
-weather_info_get_weather_summary (WeatherInfo *info)
+gweather_info_get_weather_summary (GWeatherInfo *info)
 {
     const gchar *buf;
 
-    g_return_val_if_fail (info != NULL, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
 
-    if (!info->valid)
+    if (!info->priv->valid)
 	return g_strdup (_("Retrieval failed"));
-    buf = weather_info_get_conditions (info);
+    buf = gweather_info_get_conditions (info);
     if (!strcmp (buf, "-"))
-        buf = weather_info_get_sky (info);
-    return g_strdup_printf ("%s: %s", weather_info_get_location_name (info), buf);
+        buf = gweather_info_get_sky (info);
+    return g_strdup_printf ("%s: %s", gweather_info_get_location_name (info), buf);
 }
 
 const gchar *
-weather_info_get_icon_name (WeatherInfo *info)
+gweather_info_get_icon_name (GWeatherInfo *info)
 {
-    WeatherConditions cond;
-    WeatherSky        sky;
-    time_t            current_time;
-    gboolean          daytime;
-    gchar*            icon;
-    static gchar      icon_buffer[32];
-    WeatherMoonPhase  moonPhase;
-    WeatherMoonLatitude moonLat;
-    gint              phase;
+    GWeatherInfoPrivate *priv;
+    GWeatherConditions   cond;
+    GWeatherSky          sky;
+    time_t               current_time;
+    gboolean             daytime;
+    gchar*               icon;
+    static gchar         icon_buffer[32];
+    GWeatherMoonPhase    moonPhase;
+    GWeatherMoonLatitude moonLat;
+    gint                 phase;
 
-    g_return_val_if_fail (info != NULL, NULL);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), NULL);
 
-    if (!info->valid)
+    priv = info->priv;
+
+    if (!priv->valid)
         return NULL;
 
-    cond = info->cond;
-    sky = info->sky;
+    cond = priv->cond;
+    sky = priv->sky;
 
     if (cond.significant) {
 	if (cond.phenomenon != PHENOMENON_NONE &&
@@ -1202,16 +1239,16 @@ weather_info_get_icon_name (WeatherInfo *info)
         }
     }
 
-    if (info->midnightSun ||
-	(!info->sunriseValid && !info->sunsetValid))
+    if (priv->midnightSun ||
+	(!priv->sunriseValid && !priv->sunsetValid))
 	daytime = TRUE;
-    else if (info->polarNight)
+    else if (priv->polarNight)
 	daytime = FALSE;
     else {
 	current_time = time (NULL);
 	daytime =
-	    ( !info->sunriseValid || (current_time >= info->sunrise) ) &&
-	    ( !info->sunsetValid || (current_time < info->sunset) );
+	    ( !priv->sunriseValid || (current_time >= priv->sunrise) ) &&
+	    ( !priv->sunsetValid || (current_time < priv->sunset) );
     }
 
     switch (sky) {
@@ -1246,12 +1283,12 @@ weather_info_get_icon_name (WeatherInfo *info)
      * A phase-of-moon icon is to be returned.
      * Determine which one based on the moon's location
      */
-    if (info->moonValid && weather_info_get_value_moonphase(info, &moonPhase, &moonLat)) {
+    if (priv->moonValid && gweather_info_get_value_moonphase(info, &moonPhase, &moonLat)) {
 	phase = (gint)((moonPhase * MOON_PHASES / 360.) + 0.5);
 	if (phase == MOON_PHASES) {
 	    phase = 0;
 	} else if (phase > 0 &&
-		   (RADIANS_TO_DEGREES(weather_info_get_location(info)->latitude)
+		   (RADIANS_TO_DEGREES(priv->location->latitude)
 		    < moonLat)) {
 	    /*
 	     * Locations south of the moon's latitude will see the moon in the
@@ -1277,9 +1314,9 @@ weather_info_get_icon_name (WeatherInfo *info)
 
 static gboolean
 temperature_value (gdouble temp_f,
-		   TempUnit to_unit,
+		   GWeatherTemperatureUnit to_unit,
 		   gdouble *value,
-		   TempUnit def_unit)
+		   GWeatherTemperatureUnit def_unit)
 {
     gboolean ok = TRUE;
 
@@ -1311,7 +1348,7 @@ temperature_value (gdouble temp_f,
 }
 
 static gboolean
-speed_value (gdouble knots, SpeedUnit to_unit, gdouble *value, SpeedUnit def_unit)
+speed_value (gdouble knots, GWeatherSpeedUnit to_unit, gdouble *value, GWeatherSpeedUnit def_unit)
 {
     gboolean ok = TRUE;
 
@@ -1350,7 +1387,7 @@ speed_value (gdouble knots, SpeedUnit to_unit, gdouble *value, SpeedUnit def_uni
 }
 
 static gboolean
-pressure_value (gdouble inHg, PressureUnit to_unit, gdouble *value, PressureUnit def_unit)
+pressure_value (gdouble inHg, GWeatherPressureUnit to_unit, gdouble *value, GWeatherPressureUnit def_unit)
 {
     gboolean ok = TRUE;
 
@@ -1392,7 +1429,7 @@ pressure_value (gdouble inHg, PressureUnit to_unit, gdouble *value, PressureUnit
 }
 
 static gboolean
-distance_value (gdouble miles, DistanceUnit to_unit, gdouble *value, DistanceUnit def_unit)
+distance_value (gdouble miles, GWeatherDistanceUnit to_unit, gdouble *value, GWeatherDistanceUnit def_unit)
 {
     gboolean ok = TRUE;
 
@@ -1424,225 +1461,352 @@ distance_value (gdouble miles, DistanceUnit to_unit, gdouble *value, DistanceUni
     return ok;
 }
 
+/**
+ * gweather_info_get_value_sky:
+ * @info: a #GWeatherInfo
+ * @sky: (out): a location for a #GWeatherSky.
+ *
+ * Fills out @sky with current sky conditions.
+ * Returns: TRUE is @sky is valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_sky (WeatherInfo *info, WeatherSky *sky)
+gweather_info_get_value_sky (GWeatherInfo *info, GWeatherSky *sky)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (sky != NULL, FALSE);
 
-    if (!info->valid)
+    if (!info->priv->valid)
 	return FALSE;
 
-    if (info->sky <= SKY_INVALID || info->sky >= SKY_LAST)
+    if (info->priv->sky <= SKY_INVALID || info->priv->sky >= SKY_LAST)
 	return FALSE;
 
-    *sky = info->sky;
+    *sky = info->priv->sky;
 
     return TRUE;
 }
 
+/**
+ * gweather_info_get_value_conditions:
+ * @info: a #GWeatherInfo
+ * @phenomenon: (out): a location for a #GWeatherConditionPhenomenon.
+ * @qualifier: (out): a location for a #GWeatherConditionQualifier.
+ *
+ * Fills out @phenomenon and @qualifier with current weather conditions.
+ * Returns: TRUE is out arguments are valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_conditions (WeatherInfo *info, WeatherConditionPhenomenon *phenomenon, WeatherConditionQualifier *qualifier)
+gweather_info_get_value_conditions (GWeatherInfo *info, GWeatherConditionPhenomenon *phenomenon, GWeatherConditionQualifier *qualifier)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    GWeatherInfoPrivate *priv;
+
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (phenomenon != NULL, FALSE);
     g_return_val_if_fail (qualifier != NULL, FALSE);
 
-    if (!info->valid)
+    priv = info->priv;
+
+    if (!priv->valid)
 	return FALSE;
 
-    if (!info->cond.significant)
+    if (!priv->cond.significant)
 	return FALSE;
 
-    if (!(info->cond.phenomenon > PHENOMENON_INVALID &&
-	  info->cond.phenomenon < PHENOMENON_LAST &&
-	  info->cond.qualifier > QUALIFIER_INVALID &&
-	  info->cond.qualifier < QUALIFIER_LAST))
+    if (!(priv->cond.phenomenon > PHENOMENON_INVALID &&
+	  priv->cond.phenomenon < PHENOMENON_LAST &&
+	  priv->cond.qualifier > QUALIFIER_INVALID &&
+	  priv->cond.qualifier < QUALIFIER_LAST))
         return FALSE;
 
-    *phenomenon = info->cond.phenomenon;
-    *qualifier = info->cond.qualifier;
+    *phenomenon = priv->cond.phenomenon;
+    *qualifier = priv->cond.qualifier;
 
     return TRUE;
 }
 
+/**
+ * gweather_info_get_value_temp:
+ * @info: a #GWeatherInfo
+ * @unit: the desired unit, as a #GWeatherTemperatureUnit
+ * @value: (out): the temperature value
+ *
+ * Returns: TRUE is @value is valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_temp (WeatherInfo *info, TempUnit unit, gdouble *value)
+gweather_info_get_value_temp (GWeatherInfo *info, GWeatherTemperatureUnit unit, gdouble *value)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (value != NULL, FALSE);
 
-    if (!info->valid)
+    if (!info->priv->valid)
 	return FALSE;
 
-    return temperature_value (info->temp, unit, value, info->temperature_unit);
+    return temperature_value (info->priv->temp, unit, value, info->priv->temperature_unit);
 }
 
+/**
+ * gweather_info_get_value_temp_min:
+ * @info: a #GWeatherInfo
+ * @unit: the desired unit, as a #GWeatherTemperatureUnit
+ * @value: (out): the minimum temperature value
+ *
+ * Returns: TRUE is @value is valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_temp_min (WeatherInfo *info, TempUnit unit, gdouble *value)
+gweather_info_get_value_temp_min (GWeatherInfo *info, GWeatherTemperatureUnit unit, gdouble *value)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (value != NULL, FALSE);
 
-    if (!info->valid || !info->tempMinMaxValid)
+    if (!info->priv->valid || !info->priv->tempMinMaxValid)
 	return FALSE;
 
-    return temperature_value (info->temp_min, unit, value, info->temperature_unit);
+    return temperature_value (info->priv->temp_min, unit, value, info->priv->temperature_unit);
 }
 
+/**
+ * gweather_info_get_value_temp_max:
+ * @info: a #GWeatherInfo
+ * @unit: the desired unit, as a #GWeatherTemperatureUnit
+ * @value: (out): the maximum temperature value
+ *
+ * Returns: TRUE is @value is valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_temp_max (WeatherInfo *info, TempUnit unit, gdouble *value)
+gweather_info_get_value_temp_max (GWeatherInfo *info, GWeatherTemperatureUnit unit, gdouble *value)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (value != NULL, FALSE);
 
-    if (!info->valid || !info->tempMinMaxValid)
+    if (!info->priv->valid || !info->priv->tempMinMaxValid)
 	return FALSE;
 
-    return temperature_value (info->temp_max, unit, value, info->temperature_unit);
+    return temperature_value (info->priv->temp_max, unit, value, info->priv->temperature_unit);
 }
 
+/**
+ * gweather_info_get_value_dew:
+ * @info: a #GWeatherInfo
+ * @unit: the desired unit, as a #GWeatherTemperatureUnit
+ * @value: (out): the dew point
+ *
+ * Returns: TRUE is @value is valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_dew (WeatherInfo *info, TempUnit unit, gdouble *value)
+gweather_info_get_value_dew (GWeatherInfo *info, GWeatherTemperatureUnit unit, gdouble *value)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (value != NULL, FALSE);
 
-    if (!info->valid)
+    if (!info->priv->valid)
 	return FALSE;
 
-    return temperature_value (info->dew, unit, value, info->temperature_unit);
+    return temperature_value (info->priv->dew, unit, value, info->priv->temperature_unit);
 }
 
+/**
+ * gweather_info_get_value_apparent:
+ * @info: a #GWeatherInfo
+ * @unit: the desired unit, as a #GWeatherTemperatureUnit
+ * @value: (out): the apparent temperature
+ *
+ * Returns: TRUE is @value is valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_apparent (WeatherInfo *info, TempUnit unit, gdouble *value)
+gweather_info_get_value_apparent (GWeatherInfo *info, GWeatherTemperatureUnit unit, gdouble *value)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (value != NULL, FALSE);
 
-    if (!info->valid)
+    if (!info->priv->valid)
 	return FALSE;
 
-    return temperature_value (calc_apparent (info), unit, value, info->temperature_unit);
+    return temperature_value (calc_apparent (info), unit, value, info->priv->temperature_unit);
 }
 
+/**
+ * gweather_info_get_value_update:
+ * @info: a #GWeatherInfo
+ * @value: (out) (type gulong): the time @info was last updated
+ *
+ * Returns: TRUE is @value is valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_update (WeatherInfo *info, time_t *value)
+gweather_info_get_value_update (GWeatherInfo *info, time_t *value)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (value != NULL, FALSE);
 
-    if (!info->valid)
+    if (!info->priv->valid)
 	return FALSE;
 
-    *value = info->update;
+    *value = info->priv->update;
 
     return TRUE;
 }
 
+/**
+ * gweather_info_get_value_sunrise:
+ * @info: a #GWeatherInfo
+ * @value: (out) (type gulong): the time of sunrise
+ *
+ * Returns: TRUE is @value is valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_sunrise (WeatherInfo *info, time_t *value)
+gweather_info_get_value_sunrise (GWeatherInfo *info, time_t *value)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (value != NULL, FALSE);
 
-    if (!info->valid || !info->sunriseValid)
+    if (!info->priv->valid || !info->priv->sunriseValid)
 	return FALSE;
 
-    *value = info->sunrise;
+    *value = info->priv->sunrise;
 
     return TRUE;
 }
 
+/**
+ * gweather_info_get_value_sunset:
+ * @info: a #GWeatherInfo
+ * @value: (out) (type gulong): the time of sunset
+ *
+ * Returns: TRUE is @value is valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_sunset (WeatherInfo *info, time_t *value)
+gweather_info_get_value_sunset (GWeatherInfo *info, time_t *value)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (value != NULL, FALSE);
 
-    if (!info->valid || !info->sunsetValid)
+    if (!info->priv->valid || !info->priv->sunsetValid)
 	return FALSE;
 
-    *value = info->sunset;
+    *value = info->priv->sunset;
 
     return TRUE;
 }
 
+/**
+ * gweather_info_get_value_moonphase:
+ * @info: a #GWeatherInfo
+ * @value: (out): the current moon phase (represented as the visible percentage)
+ * @lat: (out): the latitude the moon is at (???)
+ *
+ * Returns: TRUE is @value is valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_moonphase (WeatherInfo      *info,
-				  WeatherMoonPhase *value,
-				  WeatherMoonLatitude *lat)
+gweather_info_get_value_moonphase (GWeatherInfo      *info,
+				   GWeatherMoonPhase *value,
+				   GWeatherMoonLatitude *lat)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (value != NULL, FALSE);
+    g_return_val_if_fail (lat != NULL, FALSE);
 
-    if (!info->valid || !info->moonValid)
+    if (!info->priv->valid || !info->priv->moonValid)
 	return FALSE;
 
-    *value = info->moonphase;
-    *lat   = info->moonlatitude;
+    *value = info->priv->moonphase;
+    *lat   = info->priv->moonlatitude;
 
     return TRUE;
 }
 
+/**
+ * gweather_info_get_value_wind:
+ * @info: a #GWeatherInfo
+ * @unit: the desired unit, as a #GWeatherSpeedUnit
+ * @speed: (out): forecasted wind speed
+ * @direction: (out): forecasted wind direction
+ *
+ * Returns: TRUE if @speed and @direction are valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_wind (WeatherInfo *info, SpeedUnit unit, gdouble *speed, WeatherWindDirection *direction)
+gweather_info_get_value_wind (GWeatherInfo *info,
+			      GWeatherSpeedUnit unit,
+			      gdouble *speed,
+			      GWeatherWindDirection *direction)
 {
+    GWeatherInfoPrivate *priv;
     gboolean res = FALSE;
 
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (speed != NULL, FALSE);
     g_return_val_if_fail (direction != NULL, FALSE);
 
-    if (!info->valid)
+    priv = info->priv;
+
+    if (!priv->valid)
 	return FALSE;
 
-    if (info->windspeed < 0.0 || info->wind <= WIND_INVALID || info->wind >= WIND_LAST)
+    if (priv->windspeed < 0.0 || priv->wind <= WIND_INVALID || priv->wind >= WIND_LAST)
         return FALSE;
 
-    res = speed_value (info->windspeed, unit, speed, info->speed_unit);
-    *direction = info->wind;
+    res = speed_value (priv->windspeed, unit, speed, priv->speed_unit);
+    *direction = priv->wind;
 
     return res;
 }
 
+/**
+ * gweather_info_get_value_pressure:
+ * @info: a #GWeatherInfo
+ * @unit: the desired unit, as a #GWeatherPressureUnit
+ * @value: (out): forecasted pressure, expressed in @unit
+ *
+ * Returns: TRUE if @value is valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_pressure (WeatherInfo *info, PressureUnit unit, gdouble *value)
+gweather_info_get_value_pressure (GWeatherInfo *info,
+				  GWeatherPressureUnit unit,
+				  gdouble *value)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (value != NULL, FALSE);
 
-    if (!info->valid)
+    if (!info->priv->valid)
 	return FALSE;
 
-    return pressure_value (info->pressure, unit, value, info->pressure_unit);
+    return pressure_value (info->priv->pressure, unit, value, info->priv->pressure_unit);
 }
 
+/**
+ * gweather_info_get_value_visibility:
+ * @info: a #GWeatherInfo
+ * @unit: the desired unit, as a #GWeatherDistanceUnit
+ * @value: (out): forecasted visibility, expressed in @unit
+ *
+ * Returns: TRUE if @value is valid, FALSE otherwise.
+ */
 gboolean
-weather_info_get_value_visibility (WeatherInfo *info, DistanceUnit unit, gdouble *value)
+gweather_info_get_value_visibility (GWeatherInfo *info,
+				    GWeatherDistanceUnit unit,
+				    gdouble *value)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (value != NULL, FALSE);
 
-    if (!info->valid)
+    if (!info->priv->valid)
 	return FALSE;
 
-    return distance_value (info->visibility, unit, value, info->distance_unit);
+    return distance_value (info->priv->visibility, unit, value, info->priv->distance_unit);
 }
 
 /**
  * weather_info_get_upcoming_moonphases:
- * @info:   WeatherInfo containing the time_t of interest
- * @phases: An array of four time_t values that will hold the returned values.
+ * @info: a #GWeatherInfo containing the time_t of interest
+ * @phases: (out) (array fixed-size=4) (element-type gulong): An array of four
+ *    time_t values that will hold the returned values.
  *    The values are estimates of the time of the next new, quarter, full and
  *    three-quarter moons.
  *
  * Returns: gboolean indicating success or failure
  */
 gboolean
-weather_info_get_upcoming_moonphases (WeatherInfo *info, time_t *phases)
+gweather_info_get_upcoming_moonphases (GWeatherInfo *info, time_t *phases)
 {
-    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (GWEATHER_IS_INFO (info), FALSE);
     g_return_val_if_fail (phases != NULL, FALSE);
 
     return calc_moon_phases(info, phases);
@@ -1656,3 +1820,115 @@ _weather_internal_check (void)
     g_assert (G_N_ELEMENTS (conditions_str) == PHENOMENON_LAST);
     g_assert (G_N_ELEMENTS (conditions_str[0]) == QUALIFIER_LAST);
 }
+
+static void
+gweather_info_set_property (GObject *object,
+			    guint property_id,
+			    const GValue *value,
+			    GParamSpec *pspec)
+{
+    GWeatherInfo *self = GWEATHER_INFO (object);
+    GWeatherInfoPrivate *priv = self->priv;
+
+    switch (property_id) {
+    case PROP_LOCATION:
+	priv->glocation = (GWeatherLocation *) g_value_dup_boxed (value);
+	if (priv->glocation)
+	    priv->location = _weather_location_from_gweather_location (priv->glocation, NULL);
+	break;
+    case PROP_PREFS:
+	gweather_info_set_preferences (self, (const GWeatherPrefs *) g_value_get_pointer (value));
+	break;
+    case PROP_TYPE:
+	priv->forecast_type = g_value_get_int (value);
+	break;
+    default:
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+void
+gweather_info_class_init (GWeatherInfoClass *klass)
+{
+    GParamSpec *pspec;
+    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+    g_type_class_add_private (klass, sizeof(GWeatherInfoPrivate));
+
+    gobject_class->finalize = gweather_info_finalize;
+    gobject_class->set_property = gweather_info_set_property;
+
+    pspec = g_param_spec_boxed ("location",
+				"Location",
+				"The location this info represents",
+				GWEATHER_TYPE_LOCATION,
+				G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
+    g_object_class_install_property (gobject_class, PROP_LOCATION, pspec);
+
+    /* FIXME: make this a boxed */
+    pspec = g_param_spec_pointer ("preferences",
+				  "Preferences",
+				  "The preferences and defaults used by this info",
+				  G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE);
+    g_object_class_install_property (gobject_class, PROP_PREFS, pspec);
+
+    /* FIXME: glib-mkenums hangs when I add weather.h to the list of enums */
+    pspec = g_param_spec_int ("forecast-type",
+			      "Forecast type",
+			      "The type of forecast desired (list, zone or state)",
+			      0, 3, FORECAST_LIST,
+			      G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
+    g_object_class_install_property (gobject_class, PROP_TYPE, pspec);
+
+    gweather_info_signals[SIGNAL_UPDATED] = g_signal_new ("updated",
+							  GWEATHER_TYPE_INFO,
+							  G_SIGNAL_RUN_FIRST,
+							  G_STRUCT_OFFSET (GWeatherInfoClass, updated),
+							  NULL, /* accumulator */
+							  NULL, /* accu_data */
+							  g_cclosure_marshal_VOID__VOID,
+							  G_TYPE_NONE, 0);
+}
+
+/**
+ * gweather_info_new:
+ * @location: (allow-none): the desidered #GWeatherLocation (NULL for default)
+ * @forecast_type: the type of forecast requested
+ * @prefs: an object providing defaults for units, radars, etc.
+ *
+ * Returns: (transfer full): a new #GWeatherInfo
+ */
+GWeatherInfo *
+gweather_info_new (GWeatherLocation    *location,
+		   GWeatherForecastType forecast_type,
+		   const GWeatherPrefs *prefs)
+{
+    GWeatherInfo *self;
+
+    g_return_val_if_fail (prefs != NULL, NULL);
+
+    if (location != NULL)
+	self = g_object_new (GWEATHER_TYPE_INFO, "location", location, "forecast-type", forecast_type, "preferences", prefs, NULL);
+    else
+	self = g_object_new (GWEATHER_TYPE_INFO, "forecast-type", forecast_type, "preferences", prefs, NULL);
+    gweather_info_update (self);
+
+    return self;
+}
+
+GWeatherInfo *
+_gweather_info_new_clone (GWeatherInfo *other)
+{
+    GWeatherInfoPrivate *priv;
+    GWeatherPrefs prefs;
+
+    priv = other->priv;
+    prefs.temperature_unit = priv->temperature_unit;
+    prefs.speed_unit = priv->speed_unit;
+    prefs.distance_unit = priv->distance_unit;
+    prefs.pressure_unit = priv->pressure_unit;
+    prefs.use_custom_radar_url = priv->radar_url != NULL;
+    prefs.radar = priv->radar_url;
+
+    return g_object_new (GWEATHER_TYPE_INFO, "location", priv->glocation, "type", priv->forecast_type, "preferences", &prefs, NULL);
+}
diff --git a/libgweather/weather.h b/libgweather/weather.h
index 82ad643..1ec47e8 100644
--- a/libgweather/weather.h
+++ b/libgweather/weather.h
@@ -26,60 +26,29 @@
 
 
 #include <gdk-pixbuf/gdk-pixbuf.h>
+#include <libgweather/gweather-location.h>
 
 G_BEGIN_DECLS
 
 /*
- * Location
- */
-
-struct _WeatherLocation {
-    gchar *name;
-    gchar *code;
-    gchar *zone;
-    gchar *radar;
-    gboolean zone_valid;
-    gchar *coordinates;
-    gdouble  latitude;
-    gdouble  longitude;
-    gboolean latlon_valid;
-    gchar *country_code;
-    gchar *tz_hint;
-};
-
-typedef struct _WeatherLocation WeatherLocation;
-
-WeatherLocation *	weather_location_new 	(const gchar *trans_name,
-						 const gchar *code,
-						 const gchar *zone,
-						 const gchar *radar,
-						 const gchar *coordinates,
-						 const gchar *country_code,
-						 const gchar *tz_hint);
-WeatherLocation *	weather_location_clone	(const WeatherLocation *location);
-void			weather_location_free	(WeatherLocation *location);
-gboolean		weather_location_equal	(const WeatherLocation *location1,
-						 const WeatherLocation *location2);
-
-/*
  * Weather prefs
  */
 
-typedef enum _WeatherForecastType {
+typedef enum _GWeatherForecastType {
     FORECAST_STATE,
     FORECAST_ZONE,
     FORECAST_LIST
-} WeatherForecastType;
+} GWeatherForecastType;
 
-typedef enum {
+typedef enum _GWeatherTempeatureUnit {
     TEMP_UNIT_INVALID = 0,
     TEMP_UNIT_DEFAULT,
     TEMP_UNIT_KELVIN,
     TEMP_UNIT_CENTIGRADE,
     TEMP_UNIT_FAHRENHEIT
-} TempUnit;
+} GWeatherTemperatureUnit;
 
-typedef enum {
+typedef enum _GWeatherSpeedUnit {
     SPEED_UNIT_INVALID = 0,
     SPEED_UNIT_DEFAULT,
     SPEED_UNIT_MS,    /* metres per second */
@@ -87,9 +56,9 @@ typedef enum {
     SPEED_UNIT_MPH,   /* miles per hour */
     SPEED_UNIT_KNOTS, /* Knots */
     SPEED_UNIT_BFT    /* Beaufort scale */
-} SpeedUnit;
+} GWeatherSpeedUnit;
 
-typedef enum {
+typedef enum _GWeatherPressureUnit {
     PRESSURE_UNIT_INVALID = 0,
     PRESSURE_UNIT_DEFAULT,
     PRESSURE_UNIT_KPA,    /* kiloPascal */
@@ -98,85 +67,108 @@ typedef enum {
     PRESSURE_UNIT_MM_HG,  /* millimeters of mecury */
     PRESSURE_UNIT_INCH_HG, /* inches of mercury */
     PRESSURE_UNIT_ATM     /* atmosphere */
-} PressureUnit;
+} GWeatherPressureUnit;
 
-typedef enum {
+typedef enum _GWeatherDistanceUnit {
     DISTANCE_UNIT_INVALID = 0,
     DISTANCE_UNIT_DEFAULT,
     DISTANCE_UNIT_METERS,
     DISTANCE_UNIT_KM,
     DISTANCE_UNIT_MILES
-} DistanceUnit;
+} GWeatherDistanceUnit;
 
-struct _WeatherPrefs {
-    WeatherForecastType type;
+#if 0
+struct _GWeatherPrefs {
+    GWeatherForecastType type;
 
     gboolean radar;
     const char *radar_custom_url;
 
-    TempUnit temperature_unit;
-    SpeedUnit speed_unit;
-    PressureUnit pressure_unit;
-    DistanceUnit distance_unit;
+    GWeatherTemperatureUnit temperature_unit;
+    GWeatherSpeedUnit speed_unit;
+    GWeatherPressureUnit pressure_unit;
+    GWeatherDistanceUnit distance_unit;
 };
+#endif
 
-typedef struct _WeatherPrefs WeatherPrefs;
+typedef struct _GWeatherPrefs GWeatherPrefs;
 
 /*
  * Weather Info
  */
 
-typedef struct _WeatherInfo WeatherInfo;
-
-typedef void (*WeatherInfoFunc) (WeatherInfo *info, gpointer data);
-
-WeatherInfo *	_weather_info_fill			(WeatherInfo *info,
-							 WeatherLocation *location,
-							 const WeatherPrefs *prefs,
-							 WeatherInfoFunc cb,
-							 gpointer data);
-#define	weather_info_new(location, prefs, cb, data) _weather_info_fill (NULL, (location), (prefs), (cb), (data))
-#define	weather_info_update(info, prefs, cb, data) _weather_info_fill ((info), NULL, (prefs), (cb), (data))
-
-void			weather_info_abort		(WeatherInfo *info);
-WeatherInfo *		weather_info_clone		(const WeatherInfo *info);
-void			weather_info_free		(WeatherInfo *info);
-
-gboolean		weather_info_is_valid		(WeatherInfo *info);
-gboolean		weather_info_network_error	(WeatherInfo *info);
-
-void			weather_info_to_metric		(WeatherInfo *info);
-void			weather_info_to_imperial	(WeatherInfo *info);
-
-const WeatherLocation *	weather_info_get_location	(WeatherInfo *info);
-const gchar *		weather_info_get_location_name	(WeatherInfo *info);
-const gchar *		weather_info_get_update		(WeatherInfo *info);
-const gchar *		weather_info_get_sky		(WeatherInfo *info);
-const gchar *		weather_info_get_conditions	(WeatherInfo *info);
-const gchar *		weather_info_get_temp		(WeatherInfo *info);
-const gchar *		weather_info_get_temp_min	(WeatherInfo *info);
-const gchar *		weather_info_get_temp_max	(WeatherInfo *info);
-const gchar *		weather_info_get_dew		(WeatherInfo *info);
-const gchar *		weather_info_get_humidity	(WeatherInfo *info);
-const gchar *		weather_info_get_wind		(WeatherInfo *info);
-const gchar *		weather_info_get_pressure	(WeatherInfo *info);
-const gchar *		weather_info_get_visibility	(WeatherInfo *info);
-const gchar *		weather_info_get_apparent	(WeatherInfo *info);
-const gchar *		weather_info_get_sunrise	(WeatherInfo *info);
-const gchar *		weather_info_get_sunset		(WeatherInfo *info);
-const gchar *		weather_info_get_forecast	(WeatherInfo *info);
-GSList *		weather_info_get_forecast_list	(WeatherInfo *info);
-GdkPixbufAnimation *	weather_info_get_radar		(WeatherInfo *info);
-
-const gchar *		weather_info_get_temp_summary	(WeatherInfo *info);
-gchar *			weather_info_get_weather_summary(WeatherInfo *info);
-
-const gchar *		weather_info_get_icon_name	(WeatherInfo *info);
-gint			weather_info_next_sun_event	(WeatherInfo *info);
+typedef struct _GWeatherInfo GWeatherInfo;
+typedef struct _GWeatherInfoClass GWeatherInfoClass;
+typedef struct _GWeatherInfoPrivate GWeatherInfoPrivate;
+
+#define GWEATHER_TYPE_INFO                  (gweather_info_get_type ())
+#define GWEATHER_INFO(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GWEATHER_TYPE_INFO, GWeatherInfo))
+#define GWEATHER_IS_INFO(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GWEATHER_TYPE_INFO))
+#define GWEATHER_INFO_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), GWEATHER_TYPE_INFO, GWeatherInfoClass))
+#define GWEATHER_IS_INFO_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), GWEATHER_TYPE_INFO))
+#define GWEATHER_INFO_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), GWEATHER_TYPE_INFO, GWeatherInfoClass))
+
+struct _GWeatherInfo {
+    /*< private >*/
+    GObject parent_instance;
+
+    GWeatherInfoPrivate *priv;
+};
+
+struct _GWeatherInfoClass {
+    /*< private >*/
+    GObjectClass parent_class;
+
+    /*< protected >*/
+    void (*updated) (GWeatherInfo *info);
+};
+
+typedef void (*GWeatherInfoFunc) (GWeatherInfo *info, gpointer data);
+
+GType                    gweather_info_get_type            (void) G_GNUC_CONST;
+GWeatherInfo *           gweather_info_new                 (GWeatherLocation *location,
+							    GWeatherForecastType forecast_type,
+							    const GWeatherPrefs *prefs);
+void                     gweather_info_set_preferences     (GWeatherInfo *info,
+							    const GWeatherPrefs *prefs);
+void                     gweather_info_update              (GWeatherInfo *info);
+void			 gweather_info_abort		   (GWeatherInfo *info);
+
+gboolean		 gweather_info_is_valid		   (GWeatherInfo *info);
+gboolean		 gweather_info_network_error	   (GWeatherInfo *info);
+
+void			 gweather_info_to_metric	   (GWeatherInfo *info);
+void			 gweather_info_to_imperial	   (GWeatherInfo *info);
+
+const GWeatherLocation * gweather_info_get_location	   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_location_name   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_update	   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_sky		   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_conditions	   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_temp		   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_temp_min	   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_temp_max	   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_dew		   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_humidity	   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_wind		   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_pressure	   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_visibility	   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_apparent	   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_sunrise	   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_sunset	   (GWeatherInfo *info);
+const gchar *		 gweather_info_get_forecast	   (GWeatherInfo *info);
+GSList *		 gweather_info_get_forecast_list   (GWeatherInfo *info);
+GdkPixbufAnimation *	 gweather_info_get_radar	   (GWeatherInfo *info);
+
+const gchar *		 gweather_info_get_temp_summary	   (GWeatherInfo *info);
+gchar *			 gweather_info_get_weather_summary (GWeatherInfo *info);
+
+const gchar *		 gweather_info_get_icon_name	   (GWeatherInfo *info);
+gint			 gweather_info_next_sun_event	   (GWeatherInfo *info);
 
 /* values retrieving functions */
 
-enum _WeatherWindDirection {
+typedef enum _GWeatherWindDirection {
     WIND_INVALID = -1,
     WIND_VARIABLE,
     WIND_N, WIND_NNE, WIND_NE, WIND_ENE,
@@ -184,11 +176,11 @@ enum _WeatherWindDirection {
     WIND_S, WIND_SSW, WIND_SW, WIND_WSW,
     WIND_W, WIND_WNW, WIND_NW, WIND_NNW,
     WIND_LAST
-};
+} GWeatherWindDirection;
 
-typedef enum _WeatherWindDirection WeatherWindDirection;
+const gchar * gweather_wind_direction_to_string (GWeatherWindDirection wind);
 
-enum _WeatherSky {
+typedef enum _GWeatherSky {
     SKY_INVALID = -1,
     SKY_CLEAR,
     SKY_BROKEN,
@@ -196,11 +188,11 @@ enum _WeatherSky {
     SKY_FEW,
     SKY_OVERCAST,
     SKY_LAST
-};
+} GWeatherSky;
 
-typedef enum _WeatherSky WeatherSky;
+const gchar * gweather_sky_to_string (GWeatherSky sky);
 
-enum _WeatherConditionPhenomenon {
+typedef enum _GWeatherConditionPhenomenon {
     PHENOMENON_INVALID = -1,
 
     PHENOMENON_NONE,
@@ -232,11 +224,9 @@ enum _WeatherConditionPhenomenon {
     PHENOMENON_DUST_WHIRLS,
 
     PHENOMENON_LAST
-};
-
-typedef enum _WeatherConditionPhenomenon WeatherConditionPhenomenon;
+} GWeatherConditionPhenomenon;
 
-enum _WeatherConditionQualifier {
+typedef enum _GWeatherConditionQualifier {
     QUALIFIER_INVALID = -1,
 
     QUALIFIER_NONE,
@@ -256,28 +246,34 @@ enum _WeatherConditionQualifier {
     QUALIFIER_FREEZING,
 
     QUALIFIER_LAST
-};
-
-typedef enum _WeatherConditionQualifier WeatherConditionQualifier;
-typedef gdouble WeatherMoonPhase;
-typedef gdouble WeatherMoonLatitude;
-
-gboolean weather_info_get_value_update		(WeatherInfo *info, time_t *value);
-gboolean weather_info_get_value_sky		(WeatherInfo *info, WeatherSky *sky);
-gboolean weather_info_get_value_conditions	(WeatherInfo *info, WeatherConditionPhenomenon *phenomenon, WeatherConditionQualifier *qualifier);
-gboolean weather_info_get_value_temp		(WeatherInfo *info, TempUnit unit, gdouble *value);
-gboolean weather_info_get_value_temp_min	(WeatherInfo *info, TempUnit unit, gdouble *value);
-gboolean weather_info_get_value_temp_max	(WeatherInfo *info, TempUnit unit, gdouble *value);
-gboolean weather_info_get_value_dew		(WeatherInfo *info, TempUnit unit, gdouble *value);
-gboolean weather_info_get_value_apparent	(WeatherInfo *info, TempUnit unit, gdouble *value);
-gboolean weather_info_get_value_wind		(WeatherInfo *info, SpeedUnit unit, gdouble *speed, WeatherWindDirection *direction);
-gboolean weather_info_get_value_pressure	(WeatherInfo *info, PressureUnit unit, gdouble *value);
-gboolean weather_info_get_value_visibility	(WeatherInfo *info, DistanceUnit unit, gdouble *value);
-gboolean weather_info_get_value_sunrise		(WeatherInfo *info, time_t *value);
-gboolean weather_info_get_value_sunset 		(WeatherInfo *info, time_t *value);
-gboolean weather_info_get_value_moonphase       (WeatherInfo *info, WeatherMoonPhase *value, WeatherMoonLatitude *lat);
-gboolean weather_info_get_upcoming_moonphases   (WeatherInfo *info, time_t *phases);
-
+} GWeatherConditionQualifier;
+
+typedef gdouble GWeatherMoonPhase;
+typedef gdouble GWeatherMoonLatitude;
+
+gboolean gweather_info_get_value_update		(GWeatherInfo *info, time_t *value);
+gboolean gweather_info_get_value_sky		(GWeatherInfo *info, GWeatherSky *sky);
+gboolean gweather_info_get_value_conditions	(GWeatherInfo *info, GWeatherConditionPhenomenon *phenomenon, GWeatherConditionQualifier *qualifier);
+gboolean gweather_info_get_value_temp		(GWeatherInfo *info, GWeatherTemperatureUnit unit, gdouble *value);
+gboolean gweather_info_get_value_temp_min	(GWeatherInfo *info, GWeatherTemperatureUnit unit, gdouble *value);
+gboolean gweather_info_get_value_temp_max	(GWeatherInfo *info, GWeatherTemperatureUnit unit, gdouble *value);
+gboolean gweather_info_get_value_dew		(GWeatherInfo *info, GWeatherTemperatureUnit unit, gdouble *value);
+gboolean gweather_info_get_value_apparent	(GWeatherInfo *info, GWeatherTemperatureUnit unit, gdouble *value);
+gboolean gweather_info_get_value_wind		(GWeatherInfo *info, GWeatherSpeedUnit unit, gdouble *speed, GWeatherWindDirection *direction);
+gboolean gweather_info_get_value_pressure	(GWeatherInfo *info, GWeatherPressureUnit unit, gdouble *value);
+gboolean gweather_info_get_value_visibility	(GWeatherInfo *info, GWeatherDistanceUnit unit, gdouble *value);
+gboolean gweather_info_get_value_sunrise	(GWeatherInfo *info, time_t *value);
+gboolean gweather_info_get_value_sunset 	(GWeatherInfo *info, time_t *value);
+gboolean gweather_info_get_value_moonphase      (GWeatherInfo *info, GWeatherMoonPhase *value, GWeatherMoonLatitude *lat);
+gboolean gweather_info_get_upcoming_moonphases  (GWeatherInfo *info, time_t *phases);
+
+typedef struct _GWeatherConditions {
+    gboolean significant;
+    GWeatherConditionPhenomenon phenomenon;
+    GWeatherConditionQualifier qualifier;
+} GWeatherConditions;
+
+const gchar * gweather_conditions_to_string (GWeatherConditions *conditions);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]