/*  Ia Ora theme
 *  Copyright (C) 2006 Frederic Crozat - Mandriva
 *  1999 Olivier Fourdan (fourdan@xfce.org) for XFCE code
 *
 *  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.
*/

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include "ia_ora_rc_style.h"
#include "ia_ora_style.h"

static void ia_ora_rc_style_init(Ia_OraRcStyle * style);
static void ia_ora_rc_style_class_init(Ia_OraRcStyleClass * klass);
static void ia_ora_rc_style_finalize(GObject * object);
static guint ia_ora_rc_style_parse(GtkRcStyle * rc_style, GtkSettings * settings, GScanner * scanner);
static void ia_ora_rc_style_merge(GtkRcStyle * dest, GtkRcStyle * src);

static GtkStyle *ia_ora_rc_style_create_style(GtkRcStyle * rc_style);

static GtkRcStyleClass *ia_ora_parent_rc_class;

GType ia_ora_type_rc_style = 0;

enum
{
    TOKEN_GRADIENT = G_TOKEN_LAST + 1,
    TOKEN_CROSS,
    TOKEN_BLACK_CHECK,
    TOKEN_TRUE,
    TOKEN_FALSE,
};

static struct
{
  const gchar *name;
  guint        token;
}
ia_ora_rc_symbols[] =
{
  { "enable_gradient", TOKEN_GRADIENT },
  { "use_cross", TOKEN_CROSS},
  { "black_check", TOKEN_BLACK_CHECK},
  { "TRUE",            TOKEN_TRUE},
  { "FALSE",           TOKEN_FALSE},
};

void ia_ora_rc_style_register_type(GTypeModule * module)
{
    static const GTypeInfo object_info = {
        sizeof(Ia_OraRcStyleClass),
        (GBaseInitFunc) NULL,
        (GBaseFinalizeFunc) NULL,
        (GClassInitFunc) ia_ora_rc_style_class_init,
        NULL,                   /* class_finalize */
        NULL,                   /* class_data */
        sizeof(Ia_OraRcStyle),
        0,                      /* n_preallocs */
        (GInstanceInitFunc) ia_ora_rc_style_init,
	NULL
    };

    ia_ora_type_rc_style = g_type_module_register_type(module, 
						       GTK_TYPE_RC_STYLE, 
						       "Ia_OraRcStyle", 
						       &object_info, 0);
}

static void ia_ora_rc_style_init(Ia_OraRcStyle * ia_ora_rc_style)
{
  ia_ora_rc_style->enable_gradient = TRUE;
  ia_ora_rc_style->use_cross = FALSE;
  ia_ora_rc_style->black_check = FALSE;
}

static void ia_ora_rc_style_class_init(Ia_OraRcStyleClass * klass)
{
    GtkRcStyleClass *rc_style_class = GTK_RC_STYLE_CLASS(klass);
    GObjectClass *object_class = G_OBJECT_CLASS(klass);

    ia_ora_parent_rc_class = g_type_class_peek_parent(klass);

    rc_style_class->parse = ia_ora_rc_style_parse;
    rc_style_class->merge = ia_ora_rc_style_merge;
    rc_style_class->create_style = ia_ora_rc_style_create_style;
}

static guint ia_ora_parse_boolean(GScanner * scanner, GTokenType wanted_token, guint * retval)
{
    guint token;

    token = g_scanner_get_next_token(scanner);
    if(token != wanted_token)
        return wanted_token;

    token = g_scanner_get_next_token(scanner);
    if(token != G_TOKEN_EQUAL_SIGN)
        return G_TOKEN_EQUAL_SIGN;

    token = g_scanner_get_next_token(scanner);
    if(token == TOKEN_TRUE)
        *retval = TRUE;
    else if(token == TOKEN_FALSE)
        *retval = FALSE;
    else
        return TOKEN_TRUE;

    return G_TOKEN_NONE;
}


static guint ia_ora_rc_style_parse(GtkRcStyle * rc_style, GtkSettings * settings, GScanner * scanner)
{
    static GQuark scope_id = 0;
    Ia_OraRcStyle *ia_ora_rc_style = IA_ORA_RC_STYLE(rc_style);
    guint old_scope;
    guint token;
    guint i;

    /* Set up a new scope in this scanner. */

    if(!scope_id)
        scope_id = g_quark_from_string("ia_ora_theme_engine");

    /* If we bail out due to errors, we *don't* reset the scope, so the
     * error messaging code can make sense of our tokens.
     */
    old_scope = g_scanner_set_scope(scanner, scope_id);

  /* Now check if we already added our symbols to this scope
   * (in some previous call to clearlooks_rc_style_parse for the
   * same scanner.
   */

    if(!g_scanner_lookup_symbol(scanner, ia_ora_rc_symbols[0].name)) {
        for(i = 0; i < G_N_ELEMENTS (ia_ora_rc_symbols); i++)
        {
            g_scanner_scope_add_symbol(scanner, scope_id, ia_ora_rc_symbols[i].name, 
				       GINT_TO_POINTER(ia_ora_rc_symbols[i].token));
        }
    }

  /* We're ready to go, now parse the top level */

    token = g_scanner_peek_next_token(scanner);
    while(token != G_TOKEN_RIGHT_CURLY)
    {
      switch (token)
        {
            case TOKEN_GRADIENT:
                token = ia_ora_parse_boolean(scanner, TOKEN_GRADIENT, &ia_ora_rc_style->enable_gradient);
                break;
            case TOKEN_CROSS:
                token = ia_ora_parse_boolean(scanner, TOKEN_CROSS, &ia_ora_rc_style->use_cross);
                break;
            case TOKEN_BLACK_CHECK:
                token = ia_ora_parse_boolean(scanner, TOKEN_BLACK_CHECK, &ia_ora_rc_style->black_check);
		break;
            default:
                g_scanner_get_next_token(scanner);
                token = G_TOKEN_RIGHT_CURLY;
                break;
        }


        if(token != G_TOKEN_NONE)
            return token;

        token = g_scanner_peek_next_token(scanner);
    }

    g_scanner_get_next_token(scanner);

    g_scanner_set_scope(scanner, old_scope);

    return G_TOKEN_NONE;
}

static void ia_ora_rc_style_merge(GtkRcStyle * dest, GtkRcStyle * src)
{
	Ia_OraRcStyle *dest_w, *src_w;
	
	ia_ora_parent_rc_class->merge (dest, src);
	
	if (!IA_ORA_IS_RC_STYLE (src))
		return;
	
	src_w = IA_ORA_RC_STYLE (src);
	dest_w = IA_ORA_RC_STYLE (dest);

	dest_w->enable_gradient = src_w->enable_gradient;
	dest_w->use_cross = src_w->use_cross;
	dest_w->black_check= src_w->black_check;


}

/* Create an empty style suitable to this RC style
 */
static GtkStyle *ia_ora_rc_style_create_style(GtkRcStyle * rc_style)
{
    return GTK_STYLE(g_object_new(IA_ORA_TYPE_STYLE, NULL));
}
