/*
 * xlink.c : implementation of the hyperlinks detection module
 *           This version supports both XML XLinks and HTML simple links
 *
 * See Copyright for the status of this software.
 *
 * Daniel.Veillard@w3.org
 */


#ifdef WIN32
#include "win32config.h"
#else
#include "config.h"
#endif

#include <stdio.h>
#include <string.h> /* for memset() only */
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif

#include "xmlmemory.h"
#include "tree.h"
#include "parser.h"
#include "valid.h"
#include "xlink.h"

#define XLINK_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xlink/namespace/")
#define XHTML_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xhtml/")

/****************************************************************
 *								*
 *           Default setting and related functions		*
 *								*
 ****************************************************************/
 
xlinkHandlerPtr xlinkDefaultHandler = NULL;
xlinkNodeDetectFunc	xlinkDefaultDetect = NULL;

/**
 * xlinkGetDefaultHandler:
 *
 * Get the default xlink handler.
 *
 * Returns the current xlinkHandlerPtr value.
 */
xlinkHandlerPtr
xlinkGetDefaultHandler(void) {
    return(xlinkDefaultHandler);
}


/**
 * xlinkGetDefaultHandler:
 * @handler:  the new value for the xlink handler block
 *
 * Set the default xlink handlers
 */
void
xlinkSetDefaultHandler(xlinkHandlerPtr handler) {
    xlinkDefaultHandler = handler;
}

/**
 * xlinkGetDefaultDetect:
 *
 * Get the default xlink detection routine
 *
 * Returns the current function or NULL;
 */
xlinkNodeDetectFunc
xlinkGetDefaultDetect	(void) {
    return(xlinkDefaultDetect);
}

/**
 * xlinkSetDefaultDetect:
 * @func: pointer to the new detction routine.
 *
 * Set the default xlink detection routine
 */
void 
xlinkSetDefaultDetect	(xlinkNodeDetectFunc func) {
    xlinkDefaultDetect = func;
}

/****************************************************************
 *								*
 *                  The detection routines			*
 *								*
 ****************************************************************/

 
/**
 * xlinkIsLink:
 * @doc:  the document containing the node
 * @node:  the node pointer itself
 *
 * Check whether the given node carries the attributes needed
 * to be a link element (or is one of the linking elements issued
 * from the (X)HTML DtDs).
 * This routine don't try to do full checking of the link validity
 * but tries to detect and return the appropriate link type.
 *
 * Returns the xlinkType of the node (XLINK_TYPE_NONE if there is no
 *         link detected.
 */
xlinkType 
xlinkIsLink	(xmlDocPtr doc, xmlNodePtr node) {
    xmlChar *type = NULL, *role = NULL;
    xlinkType ret = XLINK_TYPE_NONE;

    if (node == NULL) return(XLINK_TYPE_NONE);
    if (doc == NULL) doc = node->doc;
    if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
        /*
	 * This is an HTML document.
	 */
    } else if ((node->ns != NULL) &&
               (!xmlStrcmp(node->ns->href, XHTML_NAMESPACE))) {
	/*
	 * !!!! We really need an IS_XHTML_ELEMENT function from HTMLtree.h @@@
	 */
        /*
	 * This is an XHTML element within an XML document
	 * Check whether it's one of the element able to carry links
	 * and in that case if it holds the attributes.
	 */
    }

    /*
     * We don't prevent a-priori having XML Linking constructs on
     * XHTML elements
     */
    type = xmlGetNsProp(node, BAD_CAST"type", XLINK_NAMESPACE);
    if (type != NULL) {
	if (xmlStrcmp(type, BAD_CAST "simple")) {
            ret = XLINK_TYPE_SIMPLE;
	} if (xmlStrcmp(type, BAD_CAST "extended")) {
	    role = xmlGetNsProp(node, BAD_CAST "role", XLINK_NAMESPACE);
	    if (role != NULL) {
		xmlNsPtr xlink;
		xlink = xmlSearchNs(doc, node, XLINK_NAMESPACE);
		if (xlink == NULL) {
		    /* Humm, fallback method */
		    if (!xmlStrcmp(role, BAD_CAST"xlink:external-linkset")) 
			ret = XLINK_TYPE_EXTENDED_SET;
		} else {
		    xmlChar buf[200];
#ifdef HAVE_SNPRINTF
		    snprintf((char *) buf, 199, "%s:external-linkset",
			     (char *) xlink->prefix);
#else
		    sprintf((char *) buf, "%s:external-linkset",
			    (char *) xlink->prefix);
#endif
		    if (!xmlStrcmp(role, buf))
			ret = XLINK_TYPE_EXTENDED_SET;

		}

	    }
	    ret = XLINK_TYPE_EXTENDED;
	}
    }

    if (type != NULL) xmlFree(type);
    if (role != NULL) xmlFree(role);
    return(ret);
}
