<commit_before>/* Egueb
 * Copyright (C) 2011 - 2013 <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.
 * If not, see <http://www.gnu.org/licenses/>.
 */

#include "egueb_svg_main_private.h"
#include "egueb_svg_renderable_container_private.h"

/* The renderable container abstracts the input handling of events
 * to propagate the input events to its children. We need to keep
 * track in a private list of every renderable child and whenever
 * a mousemove happens, also feed events into its own input object
 */
/*============================================================================*
 *                                  Local                                     *
 *============================================================================*/
static Eina_Bool _egueb_svg_renderable_container_children_process_cb(
		Egueb_Dom_Node *child, void *data)
{
	Egueb_Svg_Renderable_Container *thiz = data;
	Egueb_Dom_Node_Type type;

	/* check that it is an element */
	egueb_dom_node_type_get(child, &type);
	if (type != EGUEB_DOM_NODE_TYPE_ELEMENT_NODE)
		return EINA_TRUE;

	/* in case the tree has changed, add the new renderer */
	if (thiz->renderable_tree_changed)
	{
		if (egueb_svg_is_renderable(child))
		{
			Enesim_Renderer *r;
			r = egueb_svg_renderable_renderer_get(child);
			enesim_renderer_compound_layer_add(thiz->compound, r);
		}
	}
	if (!egueb_dom_element_process(child))
		WARN("Child failed to process");
	return EINA_TRUE;
}

static void _egueb_svg_renderable_container_tree_modified_cb(Egueb_Dom_Event *e,
		void *data)
{
	Egueb_Svg_Renderable_Container *thiz = data;
	Egueb_Dom_Node *related = NULL;
	Egueb_Dom_Node *target = NULL;

	/* check that the parent is this container */
	egueb_dom_event_mutation_related_get(e, &related);
	if (!related) return;
	if (related != EGUEB_DOM_NODE(thiz))
	{
		egueb_dom_node_unref(related);
		return;
	}
	egueb_dom_node_unref(related);

	/* get the target and check if it is of type renderable */
	egueb_dom_event_target_get(e, &target);
	if (!target) return;

	if (enesim_object_instance_inherits(ENESIM_OBJECT_INSTANCE(target),
			EGUEB_SVG_RENDERABLE_DESCRIPTOR))
		thiz->renderable_tree_changed = EINA_TRUE;
	egueb_dom_node_unref(target);
}
/*----------------------------------------------------------------------------*
 *                              Object interface                              *
 *----------------------------------------------------------------------------*/
ENESIM_OBJECT_ABSTRACT_BOILERPLATE(EGUEB_SVG_RENDERABLE_DESCRIPTOR,
		Egueb_Svg_Renderable_Container,
		Egueb_Svg_Renderable_Container_Class,
		egueb_svg_renderable_container);

static void _egueb_svg_renderable_container_class_init(void *k)
{
	Egueb_Svg_Renderable_Class *klass;

	klass = EGUEB_SVG_RENDERABLE_CLASS(k);
	klass->renderer_get = egueb_svg_renderable_container_renderer_get;
	klass->process = egueb_svg_renderable_container_process;
}

static void _egueb_svg_renderable_container_class_deinit(void *k)
{
}

static void _egueb_svg_renderable_container_instance_init(void *o)
{
	Egueb_Svg_Renderable_Container *thiz;
	Egueb_Dom_Node *n;
	Enesim_Renderer *r;

	thiz = EGUEB_SVG_RENDERABLE_CONTAINER(o);

	/* the rendering system */
	r = enesim_renderer_compound_new();
	enesim_renderer_rop_set(r, ENESIM_BLEND);
	thiz->compound = r;

	r = enesim_renderer_background_new();
	enesim_renderer_rop_set(r, ENESIM_FILL);
	enesim_renderer_background_color_set(r, 0x00000000);
	enesim_renderer_compound_layer_add(thiz->compound, enesim_renderer_ref(r));
	thiz->background = r;

	n = EGUEB_DOM_NODE(o);
	/* our event listeners */
	egueb_dom_node_event_listener_add(n,
			EGUEB_DOM_EVENT_MUTATION_NODE_INSERTED,
			_egueb_svg_renderable_container_tree_modified_cb,
			EINA_TRUE, thiz);
	egueb_dom_node_event_listener_add(n,
			EGUEB_DOM_EVENT_MUTATION_NODE_REMOVED,
			_egueb_svg_renderable_container_tree_modified_cb,
			EINA_TRUE, thiz);
	/* mark it as changed */
	thiz->renderable_tree_changed = EINA_TRUE;
}

static void _egueb_svg_renderable_container_instance_deinit(void *o)
{
	Egueb_Svg_Renderable_Container *thiz;

	thiz = EGUEB_SVG_RENDERABLE_CONTAINER(o);
	enesim_renderer_unref(thiz->background);
	enesim_renderer_unref(thiz->compound);
}
/*============================================================================*
 *                                 Global                                     *
 *============================================================================*/
Eina_Bool egueb_svg_renderable_container_process(Egueb_Svg_Renderable *r)
{
	Egueb_Svg_Renderable_Container *thiz;

	thiz = EGUEB_SVG_RENDERABLE_CONTAINER(r);
	/* in case the renderable tree has changed, be sure to clear the
	 * compound renderer and init it again
	 */
	if (thiz->renderable_tree_changed)
	{
		enesim_renderer_compound_layer_clear(thiz->compound);
		enesim_renderer_compound_layer_add(thiz->compound,
				enesim_renderer_ref(thiz->background));
	}
	/* iterate over the children and call the process there */
	egueb_dom_node_children_foreach(EGUEB_DOM_NODE(r),
			_egueb_svg_renderable_container_children_process_cb,
			thiz);
	thiz->renderable_tree_changed = EINA_FALSE;
	return EINA_TRUE;
}

Enesim_Renderer * egueb_svg_renderable_container_renderer_get(
		Egueb_Svg_Renderable *r)
{
	Egueb_Svg_Renderable_Container *thiz;

	thiz = EGUEB_SVG_RENDERABLE_CONTAINER(r);
	return enesim_renderer_ref(thiz->compound);
}

#if 0
static void _egueb_svg_renderable_container_mouse_move(Ender_Element *e,
		const char *event_name, void *event_data, void *data)
{<commit_msg>Use the new background renderer property for the compound<commit_after>/* Egueb
 * Copyright (C) 2011 - 2013 <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.
 * If not, see <http://www.gnu.org/licenses/>.
 */

#include "egueb_svg_main_private.h"
#include "egueb_svg_renderable_container_private.h"

/* The renderable container abstracts the input handling of events
 * to propagate the input events to its children. We need to keep
 * track in a private list of every renderable child and whenever
 * a mousemove happens, also feed events into its own input object
 */
/*============================================================================*
 *                                  Local                                     *
 *============================================================================*/
static Eina_Bool _egueb_svg_renderable_container_children_process_cb(
		Egueb_Dom_Node *child, void *data)
{
	Egueb_Svg_Renderable_Container *thiz = data;
	Egueb_Dom_Node_Type type;

	/* check that it is an element */
	egueb_dom_node_type_get(child, &type);
	if (type != EGUEB_DOM_NODE_TYPE_ELEMENT_NODE)
		return EINA_TRUE;

	/* in case the tree has changed, add the new renderer */
	if (thiz->renderable_tree_changed)
	{
		if (egueb_svg_is_renderable(child))
		{
			Enesim_Renderer *r;
			r = egueb_svg_renderable_renderer_get(child);
			enesim_renderer_compound_layer_add(thiz->compound, r);
		}
	}
	if (!egueb_dom_element_process(child))
		WARN("Child failed to process");
	return EINA_TRUE;
}

static void _egueb_svg_renderable_container_tree_modified_cb(Egueb_Dom_Event *e,
		void *data)
{
	Egueb_Svg_Renderable_Container *thiz = data;
	Egueb_Dom_Node *related = NULL;
	Egueb_Dom_Node *target = NULL;

	/* check that the parent is this container */
	egueb_dom_event_mutation_related_get(e, &related);
	if (!related) return;
	if (related != EGUEB_DOM_NODE(thiz))
	{
		egueb_dom_node_unref(related);
		return;
	}
	egueb_dom_node_unref(related);

	/* get the target and check if it is of type renderable */
	egueb_dom_event_target_get(e, &target);
	if (!target) return;

	if (enesim_object_instance_inherits(ENESIM_OBJECT_INSTANCE(target),
			EGUEB_SVG_RENDERABLE_DESCRIPTOR))
		thiz->renderable_tree_changed = EINA_TRUE;
	egueb_dom_node_unref(target);
}
/*----------------------------------------------------------------------------*
 *                              Object interface                              *
 *----------------------------------------------------------------------------*/
ENESIM_OBJECT_ABSTRACT_BOILERPLATE(EGUEB_SVG_RENDERABLE_DESCRIPTOR,
		Egueb_Svg_Renderable_Container,
		Egueb_Svg_Renderable_Container_Class,
		egueb_svg_renderable_container);

static void _egueb_svg_renderable_container_class_init(void *k)
{
	Egueb_Svg_Renderable_Class *klass;

	klass = EGUEB_SVG_RENDERABLE_CLASS(k);
	klass->renderer_get = egueb_svg_renderable_container_renderer_get;
	klass->process = egueb_svg_renderable_container_process;
}

static void _egueb_svg_renderable_container_class_deinit(void *k)
{
}

static void _egueb_svg_renderable_container_instance_init(void *o)
{
	Egueb_Svg_Renderable_Container *thiz;
	Egueb_Dom_Node *n;
	Enesim_Renderer *r;

	thiz = EGUEB_SVG_RENDERABLE_CONTAINER(o);

	/* the rendering system */
	r = enesim_renderer_compound_new();
	enesim_renderer_rop_set(r, ENESIM_BLEND);
	thiz->compound = r;

	r = enesim_renderer_background_new();
	enesim_renderer_rop_set(r, ENESIM_FILL);
	enesim_renderer_background_color_set(r, 0x00000000);
	enesim_renderer_compound_background_renderer_set(thiz->compound, enesim_renderer_ref(r));
	thiz->background = r;

	n = EGUEB_DOM_NODE(o);
	/* our event listeners */
	egueb_dom_node_event_listener_add(n,
			EGUEB_DOM_EVENT_MUTATION_NODE_INSERTED,
			_egueb_svg_renderable_container_tree_modified_cb,
			EINA_TRUE, thiz);
	egueb_dom_node_event_listener_add(n,
			EGUEB_DOM_EVENT_MUTATION_NODE_REMOVED,
			_egueb_svg_renderable_container_tree_modified_cb,
			EINA_TRUE, thiz);
	/* mark it as changed */
	thiz->renderable_tree_changed = EINA_TRUE;
}

static void _egueb_svg_renderable_container_instance_deinit(void *o)
{
	Egueb_Svg_Renderable_Container *thiz;

	thiz = EGUEB_SVG_RENDERABLE_CONTAINER(o);
	enesim_renderer_unref(thiz->background);
	enesim_renderer_unref(thiz->compound);
}
/*============================================================================*
 *                                 Global                                     *
 *============================================================================*/
Eina_Bool egueb_svg_renderable_container_process(Egueb_Svg_Renderable *r)
{
	Egueb_Svg_Renderable_Container *thiz;

	thiz = EGUEB_SVG_RENDERABLE_CONTAINER(r);
	/* in case the renderable tree has changed, be sure to clear the
	 * compound renderer and init it again
	 */
	if (thiz->renderable_tree_changed)
	{
		enesim_renderer_compound_layer_clear(thiz->compound);
	}
	/* iterate over the children and call the process there */
	egueb_dom_node_children_foreach(EGUEB_DOM_NODE(r),
			_egueb_svg_renderable_container_children_process_cb,
			thiz);
	thiz->renderable_tree_changed = EINA_FALSE;
	return EINA_TRUE;
}

Enesim_Renderer * egueb_svg_renderable_container_renderer_get(
		Egueb_Svg_Renderable *r)
{
	Egueb_Svg_Renderable_Container *thiz;

	thiz = EGUEB_SVG_RENDERABLE_CONTAINER(r);
	return enesim_renderer_ref(thiz->compound);
}

#if 0
static void _egueb_svg_renderable_container_mouse_move(Ender_Element *e,
		const char *event_name, void *event_data, void *data)
{
{'fraction_non_alphanumeric': 0.1472302010668855, 'fraction_numerical': 0.003282724661469019, 'mean_word_length': 4.437751004016064, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2757088', 'n_tokens_mistral': 4318, 'n_tokens_neox': 4124, 'n_words': 844}