/*
 * This file is part of libdom.
 * Licensed under the MIT License,
 *                http://www.opensource.org/licenses/mit-license.php
 * Copyright 2009 Bo Yang <struggleyb.nku@gmail.com>
 */

#ifndef dom_events_document_event_h_
#define dom_events_document_event_h_

#include <stdbool.h>

#include <dom/core/exceptions.h>
#include <dom/core/string.h>

struct dom_event;
struct dom_document;

typedef struct dom_document dom_document_event;

/**
 * The callback function which is used to process the default action of any
 * event.
 *
 * As ::dom_default_action_phase defines, we have three points in our 
 * implementation where these kinds of callbacks get invoked.
 *
 * When the implementation start to dispatch certain event, it firstly invoke
 * the following callback, which should process the event before the normal
 * event flow.
 *
 * Take a MousePressed event on a check box object as example:
 * 1. The 'pressed' event is generated by OS and catched by our UI code;
 * 2. The UI code dispatch the event to DOM;
 * 3. DOM trys to dispatch the event as what the spec said;
 * 4. Before the real event flow happens, DOM get the 
 *    dom_default_action_callback function from the 
 *    dom_events_default_action_fetcher with param
 *    DOM_DEFAULT_ACTION_STARTED, and then call it;
 * 5. The callback function invoke some System-denpendent API to make the
 *    checkbox checked and then return;
 * 6. Normal event flow goes on.
 * 7. When the implementation reach the end of the event flow, it check whether
 *    the event's default action is prevented, if it is, then go to step 8,
 *    else go to step 9.
 * 8. The event's default action get prevented, DOM get the 
 *    dom_default_action_callback function from the 
 *    dom_events_default_action_fetcher with param
 *    DOM_DEFAULT_ACTION_PREVENTED, and then call it.
 * 8. The event's default action does not get prevented, DOM get the 
 *    dom_default_action_callback function from the 
 *    dom_events_default_action_fetcher with param
 *    DOM_DEFAULT_ACTION_END, and then call it.
 *
 * @note: the point here is that we want the UI related stuff to be done
 * within the default action code. The DOM only take care of the content tree
 * and the event flow itself.
 */
typedef void (*dom_default_action_callback)(struct dom_event *evt, void *pw);

/**
 * The default action phase
 *
 * @note: we define the following three values to fetch three different types
 * of dom_default_action_callback function and their private data.
 */
typedef enum {
	DOM_DEFAULT_ACTION_STARTED = 0,
	DOM_DEFAULT_ACTION_PREVENTED,
	DOM_DEFAULT_ACTION_END,
	DOM_DEFAULT_ACTION_FINISHED
} dom_default_action_phase;

/**
 * The default action fetcher
 *
 * \param type   The type of the event
 * \param phase  The phase of the default action callback
 * \param pw     The return private data of the callback function
 * \return a callback function, NULL if there is none.
 */
typedef dom_default_action_callback (*dom_events_default_action_fetcher)
		(dom_string *type, dom_default_action_phase phase, 
		void **pw);

dom_exception _dom_document_event_create_event(dom_document_event *de,
		dom_string *type, struct dom_event **evt);
#define dom_document_event_create_event(d, t, e) \
		_dom_document_event_create_event((dom_document_event *) (d), \
		(dom_string *) (t), (struct dom_event **) (e))

dom_exception _dom_document_event_can_dispatch(dom_document_event *de,
		dom_string *namespace, dom_string *type,
		bool* can);
#define dom_document_event_can_dispatch(d, n, t, c) \
		_dom_document_event_can_dispatch((dom_document_event *) (d), \
		(dom_string *) (n), (dom_string *) (t),\
		(bool *) (c))

#endif

