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

#include "sim_gconf.h"
#include "gconf_background.h"

#define KEY_WALLPAPER "/desktop/gnome/background/picture_filename"
#define KEY_OPTIONS "/desktop/gnome/background/picture_options"
#define KEY_COLOUR "/desktop/gnome/background/primary_color"
#define ERR -1

using namespace std;

wxString backgroundUrl;
wxColour colour;
int backgroundType = STRETCHED;


bool
setBackgroundType (wxString res)
{

  if (res == _T (STRETCHED_STR))
    {
      backgroundType = STRETCHED;
      return true;
    }
  if (res == _T (NONE_STR))
    {
      backgroundType = NONE;
      return true;
    }
  if (res == _T (SCALED_STR))
    {
      backgroundType = SCALED;
      return true;
    }
  if (res == _T (CENTERED_STR))
    {
      backgroundType = CENTERED;
      return true;
    }
  if (res == _T (WALLPAPER_STR))
    {
      backgroundType = WALLPAPER;
      return true;
    }
  return false;
}

/* ---------------- Gconf2 callback functions --------------------- */
void
OnBackgroundUrlChange (GConfClient * client,
		       guint cnxn_id, GConfEntry * entry, gpointer user_data)
{
  if (gconf_entry_get_value (entry) == NULL)
    {
      cout << "Null entry" << endl;
      return;
    }
  else
    {
      if (gconf_entry_get_value (entry)->type == GCONF_VALUE_STRING)
	{
	  backgroundUrl =
	    wxString::
	    FromAscii (gconf_value_get_string
		       (gconf_entry_get_value (entry)));
	  wxGetApp().SetWallpaper (fixImage (backgroundUrl, backgroundType, colour));
	}
      else
	{
	  cout << "Invalid value?" << endl;
	  return;
	}
    }
}

void
OnBackgroundTypeChange (GConfClient * client,
			guint cnxn_id, GConfEntry * entry, gpointer user_data)
{
  if (gconf_entry_get_value (entry) == NULL)
    {
      cout << "Null entry" << endl;
      return;
    }
  else
    {
      if (gconf_entry_get_value (entry)->type == GCONF_VALUE_STRING)
	{
	  setBackgroundType (wxString::
			     FromAscii (gconf_value_get_string
					(gconf_entry_get_value (entry))));
	  wxGetApp().SetWallpaper (fixImage (backgroundUrl, backgroundType, colour));
	}
      else
	{
	  cout << "Invalid value?" << endl;
	  return;
	}
    }
}

void
OnBackgroundColourChange (GConfClient * client,
			  guint cnxn_id,
			  GConfEntry * entry, gpointer user_data)
{
  if (gconf_entry_get_value (entry) == NULL)
    {
      cout << "Null entry" << endl;
      return;
    }
  else
    {
      if (gconf_entry_get_value (entry)->type == GCONF_VALUE_STRING)
	{
	  colour.
	    Set (wxString::
		 FromAscii (gconf_value_get_string
			    (gconf_entry_get_value (entry))));
	  if (backgroundType == CENTERED)
	    wxGetApp().SetWallpaper (fixImage (backgroundUrl, backgroundType, colour));
	}
      else
	{
	  cout << "Invalid value?" << endl;
	  return;
	}
    }

}

/* ---------------- Gconf2 callback functions END ----------------- */


wxBitmap *
fixImage (wxString url, int type, wxColour c)
{
  if (url.IsEmpty ())
    return NULL;

  wxImage img = wxImage (url); 
  wxSize sz = wxGetDisplaySize();
  int w = sz.GetWidth();
  int h = sz.GetHeight();
  printf ("Image size:%d,%d Screen size:%d,%d\n", img.GetWidth (),
	  img.GetHeight (), w, h);
  // cout << wx2std(c.GetAsString(wxC2S_HTML_SYNTAX)) <<endl;
  switch (type)
    {
    case STRETCHED:
      return new wxBitmap (img.Scale (w, h, wxIMAGE_QUALITY_HIGH));
      break;
    case CENTERED:
      int x, y;
      if (img.GetWidth () > w)
	x = 0;
      else
	x = (w - img.GetWidth ()) / 2;
      if (img.GetHeight () > h)
	y = 0;
      else
	y = (h - img.GetHeight ()) / 2;


      img.Resize (wxSize (w, h), wxPoint (x, y), c.Red (), c.Green (),
		  c.Blue ());
      return new wxBitmap (img);
      break;
    default:
      return new wxBitmap (img);
      break;

    }

  return NULL;
}


wxBitmap *
getBackgroundImage ()
{

  if (!SimGconf::init ())
    return NULL;
  GConfClient *client = SimGconf::GetClient ();
  GError *err = NULL;

  gconf_client_add_dir (client, KEY_WALLPAPER, GCONF_CLIENT_PRELOAD_NONE,
			NULL);
  gconf_client_add_dir (client, KEY_OPTIONS, GCONF_CLIENT_PRELOAD_NONE, NULL);
  gconf_client_add_dir (client, KEY_COLOUR, GCONF_CLIENT_PRELOAD_NONE, NULL);
  if (!gconf_client_notify_add
      (client, KEY_WALLPAPER, OnBackgroundUrlChange, NULL, NULL, &err))
    {
      printf ("Failed to init GConf: %s", err->message);
      g_error_free (err);
      err = NULL;

    }
  gconf_client_notify_add (client, KEY_OPTIONS,
			   OnBackgroundTypeChange, NULL, NULL, NULL);
  gconf_client_notify_add (client, KEY_COLOUR,
			   OnBackgroundColourChange, NULL, NULL, NULL);


  wxString tmp;
  SimGconf::GetString (client, KEY_WALLPAPER, &backgroundUrl);
  SimGconf::GetString (client, KEY_OPTIONS, &tmp);
  SimGconf::GetColour (client, KEY_COLOUR, &colour);
  setBackgroundType (tmp);
  g_object_unref (client);
  return fixImage (backgroundUrl, backgroundType, colour);

}
