Index: trunk/autoquest-htmlmonitor/src/main/js/autoquest-htmlmonitor.js
===================================================================
--- trunk/autoquest-htmlmonitor/src/main/js/autoquest-htmlmonitor.js	(revision 1019)
+++ trunk/autoquest-htmlmonitor/src/main/js/autoquest-htmlmonitor.js	(revision 1020)
@@ -197,5 +197,5 @@
     { "tag": "video", "actions": [ "onplaying",
                                    "onpause",
-                                   "ontimeupdate" ] },
+                                   "ontimeupdate" ] }
     //{ "tag": "wbr", "actions": [  ] },
 ];
@@ -218,4 +218,9 @@
 
 /**
+ * stores the structure of the GUI of the current page
+ */
+var autoquestGUIModel;
+
+/**
  * stores events, which were recorded but not sent to the server yet
  */
@@ -242,5 +247,5 @@
         log("adding event handling attributes");
         determineDestination();
-        addEventHandlingAttributes(document.documentElement, "");
+        autoquestGUIModel = addEventHandlingAndGetJSONRepresentation(document.documentElement, "");
         
         if (document.readyState !== "complete") {
@@ -281,5 +286,5 @@
 /**
  * traverses the DOM-structure of the HTML-site and adds event handling attributes to each
- * relevant node
+ * relevant node. Furthermore returns a JSON representation of the node including the children
  * 
  * @param node       the node of the DOM structure that shall be adapted and whose children shall
@@ -288,36 +293,129 @@
  *                   the HTML-site
  */
-function addEventHandlingAttributes(node, parentPath) {
+function addEventHandlingAndGetJSONRepresentation(node, parentPath) {
     var nodePath;
     var i;
-    var k;
-    var value;
+    var jsonRepresentation = null;
+    var childRepresentation;
+    var childRepresentations = null;
     
     if (node.nodeType === Node.ELEMENT_NODE) {
-        nodePath = getNodePath(node, parentPath);
-        
-        for (i = 0; i < autoquestActionConfig.length; i++) {
-            if (getTagName(node) === autoquestActionConfig[i].tag.toLowerCase()) {
-                for (k = 0; k < autoquestActionConfig[i].actions.length; k++) {
-                    value = "handleEvent(this, '" +
-                                         autoquestActionConfig[i].actions[k] + "', '" +
-                                         nodePath + "', event);";
-
-                    if (!node.getAttribute(autoquestActionConfig[i].actions[k])) {
-                        node.setAttribute(autoquestActionConfig[i].actions[k], value);
+        jsonRepresentation = "{\"tagName\":\"" + getTagName(node) + "\",";
+        
+        if ((node.id) && (node.id !== "")) {
+            jsonRepresentation += "\"id\":\"" + node.id + "\"";
+        }
+        else {
+            jsonRepresentation += "\"index\":\"" + getNodeIndex(node) + "\"";
+        }
+        
+        addEventHandling(node, parentPath);
+        
+        if (node.childNodes.length > 0) {
+            nodePath = getNodePath(node, parentPath);
+            
+            for (i = 0; i < node.childNodes.length; i++) {
+                childRepresentation =
+                    addEventHandlingAndGetJSONRepresentation(node.childNodes[i], nodePath);
+                
+                if (childRepresentation) {
+                    if (!childRepresentations) {
+                        childRepresentations = childRepresentation;
                     }
                     else {
-                        var oldValue = node.getAttribute(autoquestActionConfig[i].actions[k]);
-                        if (oldValue.indexOf(value) < 0) {
-                            node.setAttribute(autoquestActionConfig[i].actions[k],
-                                              value + ' ' + oldValue);
-                        }
+                        childRepresentations += "," + childRepresentation;
                     }
                 }
             }
-        }
-        
-        for (i = 0; i < node.childNodes.length; i++) {
-            addEventHandlingAttributes(node.childNodes[i], nodePath);
+
+            if (childRepresentations) {
+                jsonRepresentation += ",\"children\":[" + childRepresentations + "]";
+            }
+        }
+        
+        jsonRepresentation += "}";
+    }
+    
+    return jsonRepresentation;
+}
+
+/**
+ * TODO comment
+ */
+function addEventHandling(node, parentPath) {
+    if (typeof jQuery === 'undefined') {
+        addEventHandlingWithoutJQuery(node, parentPath);
+    }
+    else {
+        addEventHandlingWithJQuery(node, parentPath);
+    }
+}
+
+/**
+ * TODO comment
+ */
+function addEventHandlingWithoutJQuery(node, parentPath) {
+    var nodePath = getNodePath(node, parentPath);
+    var tagName = getTagName(node);
+    var i;
+    var k;
+    
+    for (i = 0; i < autoquestActionConfig.length; i++) {
+        if (tagName === autoquestActionConfig[i].tag.toLowerCase()) {
+            for (k = 0; k < autoquestActionConfig[i].actions.length; k++) {
+                adaptEventHandlingAttribute(node, nodePath, autoquestActionConfig[i].actions[k]);
+            }
+        }
+    }
+}
+
+/**
+ * TODO comment
+ */
+function addEventHandlingWithJQuery(node, parentPath) {
+    var nodePath = getNodePath(node, parentPath);
+    var tagName = getTagName(node);
+    var action;
+    var parameters;
+    var i;
+    var k;
+    
+    for (i = 0; i < autoquestActionConfig.length; i++) {
+        if (tagName === autoquestActionConfig[i].tag.toLowerCase()) {
+            for (k = 0; k < autoquestActionConfig[i].actions.length; k++) {
+                action = autoquestActionConfig[i].actions[k];
+                if (jQuery(node).attr(action)) {
+                    // if there is an event handling attribute although jquery is present
+                    // edit this attribute accordingly
+                    adaptEventHandlingAttribute(node, nodePath, action);
+                }
+                else {
+                    parameters = { action : action, path : nodePath};
+                    if (jQuery(node).on) {
+                        jQuery(node).on(action.substring(2), parameters, handleJQueryEvent);
+                    }
+                    else {
+                        jQuery(node).bind(action.substring(2), parameters, handleJQueryEvent);
+                    }
+                }
+            }
+        }
+    }
+}
+
+/**
+ * TODO comment
+ */
+function adaptEventHandlingAttribute(node, nodePath, action) {
+    var value = "handleEvent(this, '" + action + "', '" + nodePath + "', event);";
+    var oldValue;
+    
+    if (!node.getAttribute(action)) {
+        node.setAttribute(action, value);
+    }
+    else {
+        oldValue = node.getAttribute(action);
+        if (oldValue.indexOf(value) < 0) {
+            node.setAttribute(action, value + ' ' + oldValue);
         }
     }
@@ -340,9 +438,5 @@
  */
 function getNodePath(node, parentPath) {
-    var nodePath = parentPath + "/";
-    var index = -1;
-    var i = 0;
-    
-    nodePath += getTagName(node);
+    var nodePath = parentPath + "/" + getTagName(node);
     
     if ((node.id) && (node.id !== "")) {
@@ -350,25 +444,15 @@
     }
     else {
-        if (node.parentNode) {
-            for (i = 0; i < node.parentNode.childNodes.length; i++) {
-                if (node.parentNode.childNodes[i].tagName === node.tagName) {
-                    index++;
-                    // if === also returns true if the nodes are not identical but only equal,
-                    // this may fail.
-                    if (node.parentNode.childNodes[i] === node) {
-                        break;
-                    }
-                }
-            }
-            
-        }
-        else {
-            index = 0;
-        }
-        
-        nodePath += "[" + index + "]";
+        nodePath += "[" + getNodeIndex(node) + "]";
     }
     
     return nodePath;
+}
+
+/**
+ * TODO comment
+ */
+function handleJQueryEvent(event) {
+    handleEvent(this, event.data.action, event.data.path, event);
 }
 
@@ -446,5 +530,5 @@
             eventObj.setKey(event.keyCode);
         }
-        else if (eventType == "onchange") {
+        else if (eventType === "onchange") {
             if ((tagName.indexOf("input") === 0) ||
                 (tagName === "textarea") ||
@@ -501,4 +585,33 @@
     
 /**
+ * determines the index of a node considering all nodes of the parent having the same name. If the
+ * node has no parent, the method returns index 0.
+ * 
+ * @param node the node for which the index must be determined
+ * 
+ * @return the index as described
+ */
+function getNodeIndex(node) {
+    var i;
+    var index = 0;
+    
+    if (node.parentNode) {
+        for (i = 0; i < node.parentNode.childNodes.length; i++) {
+            if (node.parentNode.childNodes[i].tagName === node.tagName) {
+                index++;
+                // if === also returns true if the nodes are not identical but only equal,
+                // this may fail.
+                if (node.parentNode.childNodes[i] === node) {
+                    break;
+                }
+            }
+        }
+        
+    }
+
+    return index;
+}
+    
+/**
  * sends the collected data to the server, named in the destination-variable. For this it generates
  * a JSON formatted message and uses Ajax and the <code>autoquestDestination</code> to send it to
@@ -506,5 +619,5 @@
  */
 function sendRequest() {
-    var eventList;
+    var eventList = autoquestRecordedEvents;
     var message;
     var clientId;
@@ -512,7 +625,6 @@
     var request;
     
-    if (autoquestRecordedEvents.length > 0) {
+    if (eventList.length > 1) {
         log("creating message");
-        eventList = autoquestRecordedEvents;
         
         // put the last event into the new list to allow for checks for reoccurence of the same
@@ -533,4 +645,5 @@
         message += "\"url\":\"" + document.URL + "\"},";
         
+        message += "\"guiModel\":" + autoquestGUIModel + ",";
         
         message += "\"events\":[";
@@ -674,6 +787,6 @@
             var div = document.createElement("div");
             div.setAttribute("style", "z-index:1000000; background-color:#afa; " +
-                             "border:1px black solid; position:absolute; " +
-                             "top:10px; right:10px; width:350px; height:auto");
+                             "border:1px black solid; position:absolute; top:10px; right:10px; " +
+                             "width:350px; height:auto; font-size:8pt; font-family:Helvetica");
             
             loggingInfo = document.createElement("div");
@@ -752,3 +865,2 @@
     };
 } 
-
