1 /*
  2     Copyright 2008,2009, 2010
  3         Matthias Ehmann,
  4         Michael Gerhaeuser,
  5         Carsten Miller,
  6         Bianca Valentin,
  7         Alfred Wassermann,
  8         Peter Wilfahrt
  9 
 10     This file is part of JSXGraph.
 11 
 12     JSXGraph is free software: you can redistribute it and/or modify
 13     it under the terms of the GNU Lesser General Public License as published by
 14     the Free Software Foundation, either version 3 of the License, or
 15     (at your option) any later version.
 16 
 17     JSXGraph is distributed in the hope that it will be useful,
 18     but WITHOUT ANY WARRANTY; without even the implied warranty of
 19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 20     GNU Lesser General Public License for more details.
 21 
 22     You should have received a copy of the GNU Lesser General Public License
 23     along with JSXGraph.  If not, see <http://www.gnu.org/licenses/>.
 24 */
 25 JXG.GeonextReader = new function() {
 26 
 27 this.changeOriginIds = function(board,id) {
 28     if((id == 'gOOe0') || (id == 'gXOe0') || (id == 'gYOe0') || (id == 'gXLe0') || (id == 'gYLe0')) {
 29         return board.id + id;
 30     }
 31     else {
 32         return id;
 33     }
 34 };
 35 
 36 /**
 37  * Set color properties of a geonext element.
 38  * Set stroke, fill, lighting, label and draft color attributes.
 39  * @param {Object} gxtEl element of which attributes are to set
 40  */
 41 this.colorProperties = function(gxtEl, Data) {
 42     //gxtEl.strokewidth = Data.getElementsByTagName('strokewidth')[0].firstChild.data;
 43     gxtEl.colorStroke = Data.getElementsByTagName('color')[0].getElementsByTagName('stroke')[0].firstChild.data;
 44     gxtEl.highlightStrokeColor = Data.getElementsByTagName('color')[0].getElementsByTagName('lighting')[0].firstChild.data;
 45     gxtEl.colorFill = Data.getElementsByTagName('color')[0].getElementsByTagName('fill')[0].firstChild.data;
 46     gxtEl.colorLabel = Data.getElementsByTagName('color')[0].getElementsByTagName('label')[0].firstChild.data;
 47     gxtEl.colorDraft = Data.getElementsByTagName('color')[0].getElementsByTagName('draft')[0].firstChild.data;
 48     return gxtEl;
 49 };
 50 
 51 this.firstLevelProperties = function(gxtEl, Data) {
 52     var arr = Data.childNodes,
 53         n, key;
 54     for (n=0;n<arr.length;n++) {
 55         if (arr[n].firstChild!=null && arr[n].nodeName!='data' && arr[n].nodeName!='straight') {
 56             key = arr[n].nodeName;
 57             gxtEl[key] = arr[n].firstChild.data;
 58         }
 59     };
 60     return gxtEl;
 61 };
 62 
 63 /**
 64  * Set the board properties of a geonext element.
 65  * Set active, area, dash, draft and showinfo attributes.
 66  * @param {Object} gxtEl element of which attributes are to set
 67  */
 68 this.boardProperties = function(gxtEl, Data) {
 69     //gxtEl.active = Data.getElementsByTagName('active')[0].firstChild.data;
 70     //gxtEl.area = Data.getElementsByTagName('area')[0].firstChild.data;
 71     //gxtEl.dash = Data.getElementsByTagName('dash')[0].firstChild.data;
 72     //gxtEl.draft = Data.getElementsByTagName('draft')[0].firstChild.data;
 73     //gxtEl.showinfo = Data.getElementsByTagName('showinfo')[0].firstChild.data;
 74     return gxtEl;
 75 };
 76 
 77 /**
 78  * Set the defining properties of a geonext element.
 79  * Writing the nodeName to ident; setting the name attribute and defining the element id.
 80  * @param {Object} gxtEl element of which attributes are to set
 81  */
 82 this.defProperties = function(gxtEl, Data) {
 83     if (Data.nodeType==3 || Data.nodeType==8 ) { return null; } // 3==TEXT_NODE, 8==COMMENT_NODE
 84     gxtEl.ident = Data.nodeName;
 85     if(gxtEl.ident == "text" || gxtEl.ident == "intersection" || gxtEl.ident == "composition") {
 86         gxtEl.name = '';
 87     }
 88     else {
 89         gxtEl.name = Data.getElementsByTagName('name')[0].firstChild.data;
 90     }
 91     gxtEl.id = Data.getElementsByTagName('id')[0].firstChild.data;
 92 
 93     return gxtEl;
 94 };
 95 
 96 this.visualProperties = function(gxtEl, Data) {
 97     gxtEl.visible = Data.getElementsByTagName('visible')[0].firstChild.data;
 98     gxtEl.trace = Data.getElementsByTagName('trace')[0].firstChild.data;
 99     return gxtEl;
100 };
101 
102 this.readNodes = function(gxtEl, Data, nodeType, prefix) {
103     var arr = Data.getElementsByTagName(nodeType)[0].childNodes,
104         key, n;
105     for (n=0;n<arr.length;n++) {
106         if (arr[n].firstChild!=null) {
107             if (prefix!=null) {
108                 key = prefix+JXG.capitalize(arr[n].nodeName);
109             } else {
110                 key = arr[n].nodeName;
111             }
112             gxtEl[key] = arr[n].firstChild.data;
113         }
114     };
115     return gxtEl;
116 };
117 
118 this.subtreeToString = function(root) {
119     try {
120         // firefox
121         return (new XMLSerializer()).serializeToString(root);
122     } catch (e) {
123         // IE
124         return root.xml;
125     }
126 };
127 
128 this.readImage = function(node) {
129     var pic = '',
130         nod = node;
131 
132     if (nod!=null) {
133         pic = nod.data;
134         while (nod.nextSibling!=null) {
135             nod = nod.nextSibling;
136             pic += nod.data;
137         }
138     }
139     return pic;
140 };
141 
142 this.parseImage = function(board,fileNode,level,x,y,w,h,el) {
143     var tag, wOrg, hOrg, id, im, node, picStr,
144         tmpImg;
145 
146     if (fileNode==null) { return null; }
147     if (fileNode.getElementsByTagName('src')[0]!=null) {  // Background image
148         tag = 'src';
149     } else if (fileNode.getElementsByTagName('image')[0]!=null) {
150         tag = 'image';
151     } else {
152         return null;
153     }
154 
155     picStr = this.readImage(fileNode.getElementsByTagName(tag)[0].firstChild);
156     if (picStr!='') {
157         picStr = 'data:image/png;base64,' + picStr;
158         if (tag=='src') {  // Background image
159             x = fileNode.getElementsByTagName('x')[0].firstChild.data;
160             y = fileNode.getElementsByTagName('y')[0].firstChild.data;
161             w = fileNode.getElementsByTagName('width')[0].firstChild.data;
162             h = fileNode.getElementsByTagName('height')[0].firstChild.data;
163             id = false;
164             im = new JXG.Image(board,picStr,[x,y],[w,h], level, id, false, el);
165             return im;
166         } else {  // Image bound to an element
167             /*
168                 Read the original dimensions, i.e. the ratio h/w,
169                 with the help of a temporary image.
170                 We have to wait until the image is loaded, therefore
171                 we need "onload".
172             */
173             tmpImg = new Image();
174             tmpImg.src = picStr;
175             id = el.id+'_image';
176             tmpImg.onload = function(){
177                 // Now, we can read the original dimensions of the image.
178                 var wOrg = this.width,
179                     hOrg = this.height,
180                     xf, y, wf, hf, im, tRot;
181                 if (el.elementClass == JXG.OBJECT_CLASS_LINE) {
182                     // A line containing an image, runs through the horizontal middle 
183                     // of the image.
184                     xf = function(){ return el.point1.X(); };
185                     wf = function(){ return el.point1.Dist(el.point2); };
186                     hf = function(){ return wf()*hOrg/wOrg; };
187                     yf = function(){ return el.point1.Y()-hf()*0.5; };
188                     im = new JXG.Image(board, picStr, [xf,yf], [wf,hf], level, id, false, el);
189                     tRot = board.create('transform', 
190                         [function(){return Math.atan2(el.point2.Y()-el.point1.Y(),el.point2.X()-el.point1.X())}, 
191                          el.point1
192                         ], {type:'rotate'}); 
193                     tRot.bindTo(im);
194                 } else if (el.elementClass == JXG.OBJECT_CLASS_POINT) {
195                     wf = function(){ return wOrg/board.stretchX; };
196                     hf = function(){ return hOrg/board.stretchY; };
197                     xf = function(){ return el.X()-wf()*0.5; };
198                     yf = function(){ return el.Y()-hf()*0.5; };
199                     
200                     im = new JXG.Image(board, picStr, [xf,yf], [wf,hf], level, id, false, el);
201                     //el.setProperty({size:function(){ return 0.5*Math.min(wf(),hf()); }});
202                     el.setProperty('size:'+(0.5*Math.min(wOrg,hOrg)), 'opacity:0.0', 
203                                    'highlightFillOpacity:0.0', 'highlightStrokeOpacity:0.0', 
204                                    'withLabel:false');
205                     board.renderer.hide(el.label.content);
206                 } else if (el.elementClass == JXG.OBJECT_CLASS_CIRCLE) {
207                     // A circle containing an image
208                     wf = function(){ return 2.0*el.Radius(); };
209                     hf = function(){ return wf()*hOrg/wOrg; };
210                     xf = function(){ return el.midpoint.X()-wf()*0.5; };
211                     yf = function(){ return el.midpoint.Y()-hf()*0.5; };
212                     im = new JXG.Image(board, picStr, [xf,yf], [wf,hf], level, id, false, el);
213                 } else {
214                     im = new JXG.Image(board, picStr, [x,y], [w,h], level, id, false, el);
215                     el.image = im;
216                 }
217             };
218         }
219         return im;
220     }
221 };
222 
223 this.readConditions = function(node,board) {
224     var i, s, e, ob;
225     board.conditions = '';
226     if (node!=null) {
227         for(i=0; i<node.getElementsByTagName('data').length; i++) {
228             ob = node.getElementsByTagName('data')[i];
229             s = JXG.GeonextReader.subtreeToString(ob);
230             board.conditions += s;
231         }
232     }
233 };
234 
235 this.printDebugMessage = function(outputEl,gxtEl,nodetyp,success) {
236     // document.getElementById(outputEl).innerHTML += "* " + success + ":  " + nodetyp + " " + gxtEl.name + " " + gxtEl.id + "<br>\n";
237 };
238 
239 /**
240  * Reading the elements of a geonext file
241  * @param {XMLTree} tree expects the content of the parsed geonext file returned by function parseFF/parseIE
242  * @param {Object} board board object
243  */
244 this.readGeonext = function(tree,board) {
245     var boardTmp = {}, // AW: Why do we need boardTmp?
246         snap, gridX, gridY, gridDash, gridColor, gridOpacity, grid,
247         xmlNode,
248         axisX, axisY, bgcolor, opacity,
249         elChildNodes,
250         s, Data, inter, boardData, el,
251         strFir, strLas;
252 
253     board.options.layer.sector = board.options.layer.angle;
254     board.options.layer.circle = board.options.layer.angle;
255     boardData = tree.getElementsByTagName('board')[0];
256     boardTmp.ident = "board";
257     boardTmp.id = boardData.getElementsByTagName('id')[0].firstChild.data;
258     boardTmp.width = boardData.getElementsByTagName('width')[0].firstChild.data;
259     boardTmp.height = boardData.getElementsByTagName('height')[0].firstChild.data;
260 
261     xmlNode = boardData.getElementsByTagName('fontsize')[0];
262     boardTmp.fontSize = (xmlNode != null) ? document.body.style.fontSize = xmlNode.firstChild.data : document.body.style.fontSize;
263     boardTmp.modus = boardData.getElementsByTagName('modus')[0].firstChild.data;
264 
265     xmlNode =  boardData.getElementsByTagName('coordinates')[0].getElementsByTagName('origin')[0];
266     boardTmp.originX = xmlNode.getElementsByTagName('x')[0].firstChild.data;
267     boardTmp.originY = xmlNode.getElementsByTagName('y')[0].firstChild.data;
268 
269     xmlNode =  boardData.getElementsByTagName('coordinates')[0].getElementsByTagName('zoom')[0];
270     boardTmp.zoomX = xmlNode.getElementsByTagName('x')[0].firstChild.data;
271     boardTmp.zoomY = xmlNode.getElementsByTagName('y')[0].firstChild.data;
272 
273     xmlNode = boardData.getElementsByTagName('coordinates')[0].getElementsByTagName('unit')[0];
274     boardTmp.unitX = xmlNode.getElementsByTagName('x')[0].firstChild.data;
275     boardTmp.unitY = xmlNode.getElementsByTagName('y')[0].firstChild.data;
276 
277     xmlNode = boardData.getElementsByTagName('coordinates')[0].getElementsByTagName('viewport')[0];
278     boardTmp.viewportTop = xmlNode.getElementsByTagName('top')[0].firstChild.data;
279     boardTmp.viewportLeft = xmlNode.getElementsByTagName('left')[0].firstChild.data;
280     boardTmp.viewportBottom = xmlNode.getElementsByTagName('bottom')[0].firstChild.data;
281     boardTmp.viewportRight = xmlNode.getElementsByTagName('right')[0].firstChild.data;
282 
283     boardTmp.options = JXG.deepCopy(board.options);
284     
285     this.readConditions(boardData.getElementsByTagName('conditions')[0],boardTmp);
286     board.origin = {};
287     board.origin.usrCoords = [1, 0, 0];
288     board.origin.scrCoords = [1, 1*boardTmp.originX, 1*boardTmp.originY];
289     board.zoomX = 1*boardTmp.zoomX;
290     board.zoomY = 1*boardTmp.zoomY;
291     board.unitX = 1*boardTmp.unitX;
292     board.unitY = 1*boardTmp.unitY;
293     board.updateStretch();
294 
295     if (board.options.takeSizeFromFile) {
296         board.resizeContainer(boardTmp.width,boardTmp.height);
297         //board.setBoundingBox([1*boardTmp.viewportLeft,1*boardTmp.viewportTop,
298         //                      1*boardTmp.viewportRight,1*boardTmp.viewportBottom],true);
299     }
300 
301     if(1*boardTmp.options.text.fontSize != 0) {
302         board.options.text.fontSize = 1*boardTmp.options.text.fontSize;
303     }
304     else {
305         board.options.text.fontSize = 12;
306     }
307     board.geonextCompatibilityMode = true;
308 
309     delete(JXG.JSXGraph.boards[board.id]);
310     board.id = boardTmp.id;
311 
312     JXG.JSXGraph.boards[board.id] = board;
313     board.initGeonextBoard();
314     // Update of properties during update() is not necessary in GEONExT files
315     // But it maybe necessary if we construct with JavaScript afterwards
316     board.renderer.enhancedRendering = true;
317     
318     // Read background image
319     JXG.GeonextReader.parseImage(board,boardData.getElementsByTagName('file')[0],board.options.layer['image']); 
320 
321     // Eigenschaften der Zeichenflaeche setzen
322     // das Grid zeichnen
323     // auf Kaestchen springen?
324     snap = (boardData.getElementsByTagName('coordinates')[0].getElementsByTagName('snap')[0].firstChild.data == "true") ? board.options.grid.snapToGrid = true : null;
325     gridX = (boardData.getElementsByTagName('grid')[1].getElementsByTagName('x')[0].firstChild.data) ? board.options.grid.gridX = boardData.getElementsByTagName('grid')[1].getElementsByTagName('x')[0].firstChild.data*1 : null;
326     gridY = (boardData.getElementsByTagName('grid')[1].getElementsByTagName('y')[0].firstChild.data) ? board.options.grid.gridY = boardData.getElementsByTagName('grid')[1].getElementsByTagName('y')[0].firstChild.data*1 : null;
327     board.calculateSnapSizes();
328     gridDash = boardData.getElementsByTagName('grid')[1].getElementsByTagName('dash')[0].firstChild.data;
329     board.options.grid.gridDash = JXG.str2Bool(gridDash);
330     gridColor = boardData.getElementsByTagName('grid')[1].getElementsByTagName('color')[0].firstChild.data;
331     if (gridColor.length=='9' && gridColor.substr(0,1)=='#') {
332         gridOpacity = gridColor.substr(7,2);
333         gridOpacity = parseInt(gridOpacity.toUpperCase(),16)/255;
334         gridColor = gridColor.substr(0,7);
335     }
336     else {
337         gridOpacity = '1';
338     }
339     board.options.grid.gridColor = gridColor;
340     board.options.grid.gridOpacity = gridOpacity;
341     grid = (boardData.getElementsByTagName('coordinates')[0].getElementsByTagName('grid')[0].firstChild.data == "true") ? board.renderer.drawGrid(board) : null;
342 
343     if(boardData.getElementsByTagName('coordinates')[0].getElementsByTagName('coord')[0].firstChild.data == "true") {
344 //        var p1coords = new JXG.Coords(JXG.COORDS_BY_SCREEN, [0, 0], board);
345 //        var p2coords = new JXG.Coords(JXG.COORDS_BY_SCREEN, [board.canvasWidth, board.canvasHeight], board);
346 
347 //        var axisX = board.create('axis', [[p1coords.usrCoords[1], 0], [p2coords.usrCoords[1], 0]]);
348         axisX = board.create('axis', [[0, 0], [1, 0]]);
349         axisX.setProperty('strokeColor:'+axisX.visProp['strokeColor'],'strokeWidth:'+axisX.visProp['strokeWidth'],
350                           'fillColor:none','highlightStrokeColor:'+axisX.visProp['highlightStrokeColor'],
351                           'highlightFillColor:none', 'visible:true');
352 //        var axisY = board.create('axis', [[0, p2coords.usrCoords[2]], [0, p1coords.usrCoords[2]]]);
353         axisY = board.create('axis', [[0, 0], [0, 1]]);
354         axisY.setProperty('strokeColor:'+axisY.visProp['strokeColor'],'strokeWidth:'+axisY.visProp['strokeWidth'],
355                           'fillColor:none','highlightStrokeColor:'+axisY.visProp['highlightStrokeColor'],
356                           'highlightFillColor:none', 'visible:true');
357     }
358     bgcolor = boardData.getElementsByTagName('background')[0].getElementsByTagName('color')[0].firstChild.data;
359     opacity = 1;
360     if (bgcolor.length=='9' && bgcolor.substr(0,1)=='#') {
361         opacity = bgcolor.substr(7,2);
362         bgcolor = bgcolor.substr(0,7);
363     }
364     board.containerObj.style.backgroundColor = bgcolor;
365 
366     elChildNodes = tree.getElementsByTagName("elements")[0].childNodes;
367     for (s=0; s<elChildNodes.length; s++) (
368     function(s) {
369         var i,
370             gxtEl = {},
371             l, x, y, w, h, c, numberDefEls,
372             umkreisId, umkreisName,
373             defEl = [],
374             defElN = [],
375             defElV = [],
376             defElT = [],
377             defElD = [],
378             defElDr = [],
379             defElSW = [],
380             defElColStr = [],
381             defElHColStr = [],
382             defElColF = [],
383             defElColL = [],
384             el,  arcId, pointId, line1Id, line2Id, pid, lid, aid, cid, p, inter;
385 
386         Data = elChildNodes[s];
387         gxtEl = JXG.GeonextReader.defProperties(gxtEl, Data);
388         if (gxtEl==null) return; // Text nodes are skipped.
389 
390         switch(Data.nodeName.toLowerCase()) {
391             case "point":
392                 gxtEl = JXG.GeonextReader.boardProperties(gxtEl, Data);
393                 gxtEl = JXG.GeonextReader.colorProperties(gxtEl, Data);
394                 gxtEl = JXG.GeonextReader.visualProperties(gxtEl, Data);
395                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
396                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'data'); // x and y
397                 gxtEl.fixed = Data.getElementsByTagName('fix')[0].firstChild.data;
398                 try {
399                     p = new JXG.Point(board, [1*gxtEl.x, 1*gxtEl.y], gxtEl.id, gxtEl.name, true);
400                     p.setProperty('strokeColor:'+gxtEl.colorStroke,'strokeWidth:'+gxtEl.strokewidth,
401                                   'fillColor:'+gxtEl.colorStroke,'highlightStrokeColor:'+gxtEl.highlightStrokeColor,
402                                   'highlightFillColor:'+gxtEl.highlightStrokeColor,'labelColor:'+gxtEl.colorLabel,
403                                   'visible:'+gxtEl.visible,'fixed:'+gxtEl.fixed,'draft:'+gxtEl.draft);
404                     p.setStyle(1*gxtEl.style);
405                     p.traced = (gxtEl.trace=='false') ? false : true;
406                     JXG.GeonextReader.printDebugMessage('debug',gxtEl,Data.nodeName,'OK');
407                     JXG.GeonextReader.parseImage(board,Data,board.options.layer['image'],0,0,0,0,p);
408                 } catch(e) {
409                     alert(e);
410                 }
411                 break;
412             case "line":
413                 gxtEl = JXG.GeonextReader.boardProperties(gxtEl, Data);
414                 gxtEl = JXG.GeonextReader.colorProperties(gxtEl, Data);
415                 gxtEl = JXG.GeonextReader.visualProperties(gxtEl, Data);
416                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
417                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'data');
418                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'straight', 'straight');
419 
420                 gxtEl.first = JXG.GeonextReader.changeOriginIds(board,gxtEl.first);
421                 gxtEl.last = JXG.GeonextReader.changeOriginIds(board,gxtEl.last);
422 
423                 l = new JXG.Line(board, gxtEl.first, gxtEl.last, gxtEl.id, gxtEl.name);
424                 JXG.GeonextReader.parseImage(board,Data,board.options.layer['image'],0,0,0,0,l);
425 
426                 gxtEl.straightFirst = (gxtEl.straightFirst=='false') ? false : true;
427                 gxtEl.straightLast = (gxtEl.straightLast=='false') ? false : true;
428                 l.setStraight(gxtEl.straightFirst, gxtEl.straightLast);
429                 l.setProperty('strokeColor:'+gxtEl.colorStroke,'strokeWidth:'+gxtEl.strokewidth,
430                               'fillColor:'+gxtEl.colorFill,'highlightStrokeColor:'+gxtEl.highlightStrokeColor,
431                               'highlightFillColor:'+gxtEl.colorFill, 'labelColor:'+gxtEl.colorLabel,
432                               'visible:'+gxtEl.visible, 'dash:'+gxtEl.dash,'draft:'+gxtEl.draft);
433                 l.traced = (gxtEl.trace=='false') ? false : true;
434                 JXG.GeonextReader.printDebugMessage('debug',gxtEl,Data.nodeName,'OK');
435                 break;
436             case "circle":
437                 gxtEl = JXG.GeonextReader.boardProperties(gxtEl, Data);
438                 gxtEl = JXG.GeonextReader.colorProperties(gxtEl, Data);
439                 gxtEl = JXG.GeonextReader.visualProperties(gxtEl, Data);
440                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
441                 gxtEl.midpoint = Data.getElementsByTagName('data')[0].getElementsByTagName('midpoint')[0].firstChild.data;
442 
443                 if(Data.getElementsByTagName('data')[0].getElementsByTagName('radius').length > 0) {
444                     gxtEl.radiuspoint = Data.getElementsByTagName('data')[0].getElementsByTagName('radius')[0].firstChild.data;
445                     gxtEl.radius = null;
446                     gxtEl.method = "twoPoints";
447                 }
448                 else if(Data.getElementsByTagName('data')[0].getElementsByTagName('radiusvalue').length > 0) {
449                     gxtEl.radiuspoint = null;
450                     gxtEl.radius = Data.getElementsByTagName('data')[0].getElementsByTagName('radiusvalue')[0].firstChild.data;
451                     gxtEl.radiusnum = Data.getElementsByTagName('data')[0].getElementsByTagName('radiusnum')[0].firstChild.data;
452                     gxtEl.method = "pointRadius";
453                 }
454                 if(gxtEl.method == "twoPoints") {
455                     if(board.objects[gxtEl.radiuspoint].type == JXG.OBJECT_TYPE_LINE) {
456                         gxtEl.method = "pointLine";
457                         gxtEl.radiuspoint = JXG.GeonextReader.changeOriginIds(board,gxtEl.radiuspoint);
458                     }
459                     else if(board.objects[gxtEl.radiuspoint].type == JXG.OBJECT_TYPE_CIRCLE) {
460                         gxtEl.method = "pointCircle";
461                     }
462                 }
463                 if (gxtEl.method=='pointRadius') {
464                     gxtEl.midpoint = JXG.GeonextReader.changeOriginIds(board,gxtEl.midpoint);
465                     c = new JXG.Circle(board, gxtEl.method, gxtEl.midpoint,
466                                         gxtEl.radius, gxtEl.id, gxtEl.name);
467                 } else {
468                     gxtEl.midpoint = JXG.GeonextReader.changeOriginIds(board,gxtEl.midpoint);
469                     c = new JXG.Circle(board, gxtEl.method, gxtEl.midpoint, gxtEl.radiuspoint,
470                                         gxtEl.id, gxtEl.name);
471                 }
472                 JXG.GeonextReader.parseImage(board,Data,board.options.layer['image'],0,0,0,0,c);
473                 c.setProperty('strokeColor:'+gxtEl.colorStroke,'strokeWidth:'+gxtEl.strokewidth,
474                               'fillColor:'+gxtEl.colorFill,'highlightStrokeColor:'+gxtEl.highlightStrokeColor,
475                               'highlightFillColor:'+gxtEl.colorFill,'visible:'+gxtEl.visible,'labelColor:'+gxtEl.colorLabel,
476                               'dash:'+gxtEl.dash,'draft:'+gxtEl.draft);
477                 c.traced = (gxtEl.trace=='false') ? false : true;
478                 JXG.GeonextReader.printDebugMessage('debug',gxtEl,Data.nodeName,'OK');
479                 break;
480             case "slider":
481                 gxtEl = JXG.GeonextReader.colorProperties(gxtEl, Data);
482                 gxtEl = JXG.GeonextReader.boardProperties(gxtEl, Data);
483                 gxtEl = JXG.GeonextReader.visualProperties(gxtEl, Data);
484                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
485 
486                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'data');
487                 gxtEl.fixed = Data.getElementsByTagName('fix')[0].firstChild.data;
488                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'animate', 'animate');
489                 try {
490                     p = new JXG.Point(board, [1*gxtEl.x, 1*gxtEl.y], gxtEl.id, gxtEl.name, true);
491                     JXG.GeonextReader.parseImage(board,Data,board.options.layer['point'],0,0,0,0,p);
492                     gxtEl.parent = JXG.GeonextReader.changeOriginIds(board,gxtEl.parent);
493                     p.makeGlider(gxtEl.parent);
494                     p.setProperty('strokeColor:'+gxtEl.colorStroke,'strokeWidth:'+gxtEl.strokewidth,
495                                   'fillColor:'+gxtEl.colorStroke,'highlightStrokeColor:'+gxtEl.highlightStrokeColor,
496                                   'highlightFillColor:'+gxtEl.highlightStrokeColor,'visible:'+gxtEl.visible,
497                                   'fixed:'+gxtEl.fixed,'labelColor:'+gxtEl.colorLabel,'draft:'+gxtEl.draft);
498                     p.onPolygon = JXG.str2Bool(gxtEl.onpolygon);
499                     p.traced = (gxtEl.trace=='false') ? false : true;
500                     p.setStyle(1*gxtEl.style);
501                     JXG.GeonextReader.printDebugMessage('debug',gxtEl,Data.nodeName,'OK');
502                 } catch(e) {
503                     //$('debug').innerHTML += "* <b>Err:</b>  Slider " + gxtEl.name + " " + gxtEl.id + ': '+ gxtEl.parent +"<br>\n";
504                 }
505                 break;
506             case "cas":
507                 gxtEl = JXG.GeonextReader.boardProperties(gxtEl, Data);
508                 gxtEl = JXG.GeonextReader.colorProperties(gxtEl, Data);
509                 gxtEl = JXG.GeonextReader.visualProperties(gxtEl, Data);
510                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
511                 //gxtEl.showcoord = Data.getElementsByTagName('showcoord')[0].firstChild.data;
512                 gxtEl.fixed = Data.getElementsByTagName('fix')[0].firstChild.data;
513                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'data');
514                 p = new JXG.Point(board, [1*gxtEl.xval, 1*gxtEl.yval], gxtEl.id, gxtEl.name, true);
515                 JXG.GeonextReader.parseImage(board,Data,board.options.layer['point'],0,0,0,0,p);
516                 p.addConstraint([gxtEl.x,gxtEl.y]);
517                 p.setProperty('strokeColor:'+gxtEl.colorStroke,'strokeWidth:'+gxtEl.strokewidth,
518                               'fillColor:'+gxtEl.colorStroke,'highlightStrokeColor:'+gxtEl.highlightStrokeColor,
519                               'highlightFillColor:'+gxtEl.highlightStrokeColor,'visible:'+gxtEl.visible,
520                               'fixed:'+gxtEl.fixed,'labelColor:'+gxtEl.colorLabel,'draft:'+gxtEl.draft);
521                 p.traced = (gxtEl.trace=='false') ? false : true;
522                 p.setStyle(1*gxtEl.style);
523                 JXG.GeonextReader.printDebugMessage('debug',gxtEl,Data.nodeName,'OK');
524                 break;
525             case "intersection":
526                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'data');
527                 xmlNode = Data.getElementsByTagName('first')[1];
528                 gxtEl.outputFirstId = xmlNode.getElementsByTagName('id')[0].firstChild.data;  // 1 statt 0
529                 gxtEl.outputFirstName = xmlNode.getElementsByTagName('name')[0].firstChild.data;
530                 gxtEl.outputFirstVisible = xmlNode.getElementsByTagName('visible')[0].firstChild.data;
531                 gxtEl.outputFirstTrace = xmlNode.getElementsByTagName('trace')[0].firstChild.data;
532 
533                 gxtEl.outputFirstFixed = xmlNode.getElementsByTagName('fix')[0].firstChild.data;
534                 gxtEl.outputFirstStyle = xmlNode.getElementsByTagName('style')[0].firstChild.data;
535                 gxtEl.outputFirstStrokewidth =  xmlNode.getElementsByTagName('strokewidth')[0].firstChild.data;
536 
537                 xmlNode = Data.getElementsByTagName('first')[1].getElementsByTagName('color')[0];
538                 gxtEl.outputFirstColorStroke = xmlNode.getElementsByTagName('stroke')[0].firstChild.data;
539                 gxtEl.outputFirstHighlightStrokeColor = xmlNode.getElementsByTagName('lighting')[0].firstChild.data;
540                 gxtEl.outputFirstColorFill = xmlNode.getElementsByTagName('fill')[0].firstChild.data;
541                 gxtEl.outputFirstColorLabel = xmlNode.getElementsByTagName('label')[0].firstChild.data;
542                 gxtEl.outputFirstColorDraft = xmlNode.getElementsByTagName('draft')[0].firstChild.data;
543 
544                 gxtEl.first = JXG.GeonextReader.changeOriginIds(board,gxtEl.first);
545                 gxtEl.last = JXG.GeonextReader.changeOriginIds(board,gxtEl.last);
546                 if( (((board.objects[gxtEl.first]).type == (board.objects[gxtEl.last]).type) && ((board.objects[gxtEl.first]).type == JXG.OBJECT_TYPE_LINE || (board.objects[gxtEl.first]).type == JXG.OBJECT_TYPE_ARROW))
547                      || (((board.objects[gxtEl.first]).type == JXG.OBJECT_TYPE_LINE) && ((board.objects[gxtEl.last]).type == JXG.OBJECT_TYPE_ARROW))
548                      || (((board.objects[gxtEl.last]).type == JXG.OBJECT_TYPE_LINE) && ((board.objects[gxtEl.first]).type == JXG.OBJECT_TYPE_ARROW)) ) {
549                     inter = new JXG.Intersection(board, gxtEl.id, board.objects[gxtEl.first],
550                                                      board.objects[gxtEl.last], gxtEl.outputFirstId, '',
551                                                      gxtEl.outputFirstName, '');
552                     /* offensichtlich braucht man dieses if doch */
553                     if(gxtEl.outputFirstVisible == "false") {
554                         inter.hideElement();
555                     }
556                     inter.p.setProperty('strokeColor:'+gxtEl.outputFirstColorStroke,
557                                         'strokeWidth:'+gxtEl.outputFirstStrokewidth,
558                                         //'fillColor:'+gxtEl.outputFirstColorFill,
559                                         'fillColor:'+gxtEl.outputFirstColorStroke,
560                                         'highlightStrokeColor:'+gxtEl.outputFirstHighlightStrokeColor,
561                                         'highlightFillColor:'+gxtEl.outputFirstHighlightStrokeColor,
562                                         //'highlightFillColor:'+gxtEl.outputFirstColorFill,
563                                         'visible:'+gxtEl.outputFirstVisible,
564                                         'labelColor:'+gxtEl.outputFirstColorLabel,
565                                         'draft:'+gxtEl.draft);
566                     inter.p.setStyle(1*gxtEl.outputFirstStyle);
567                     inter.p.traced = (gxtEl.outputFirstTrace=='false') ? false : true;
568                 }
569                 else {
570                     //gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'last','outputLast');
571                     xmlNode = Data.getElementsByTagName('last')[1];
572                     gxtEl.outputLastId = xmlNode.getElementsByTagName('id')[0].firstChild.data;
573                     gxtEl.outputLastName = xmlNode.getElementsByTagName('name')[0].firstChild.data;
574                     gxtEl.outputLastVisible = xmlNode.getElementsByTagName('visible')[0].firstChild.data;
575                     gxtEl.outputLastTrace = xmlNode.getElementsByTagName('trace')[0].firstChild.data;
576                     gxtEl.outputLastFixed = xmlNode.getElementsByTagName('fix')[0].firstChild.data;
577                     gxtEl.outputLastStyle = xmlNode.getElementsByTagName('style')[0].firstChild.data;
578                     gxtEl.outputLastStrokewidth = xmlNode.getElementsByTagName('strokewidth')[0].firstChild.data;
579 
580                     xmlNode = Data.getElementsByTagName('last')[1].getElementsByTagName('color')[0];
581                     gxtEl.outputLastColorStroke = xmlNode.getElementsByTagName('stroke')[0].firstChild.data;
582                     gxtEl.outputLastHighlightStrokeColor = xmlNode.getElementsByTagName('lighting')[0].firstChild.data;
583                     gxtEl.outputLastColorFill = xmlNode.getElementsByTagName('fill')[0].firstChild.data;
584                     gxtEl.outputLastColorLabel = xmlNode.getElementsByTagName('label')[0].firstChild.data;
585                     gxtEl.outputLastColorDraft = xmlNode.getElementsByTagName('draft')[0].firstChild.data;
586 
587                     inter = new JXG.Intersection(board, gxtEl.id, board.objects[gxtEl.first],
588                                             board.objects[gxtEl.last], gxtEl.outputFirstId, gxtEl.outputLastId,
589                                             gxtEl.outputFirstName, gxtEl.outputLastName);
590                     inter.p1.setProperty('strokeColor:'+gxtEl.outputFirstColorStroke,
591                                         'strokeWidth:'+gxtEl.outputFirstStrokewidth,
592                                         //'fillColor:'+gxtEl.outputFirstColorFill,
593                                         'fillColor:'+gxtEl.outputFirstColorStroke,
594                                         'highlightStrokeColor:'+gxtEl.outputFirstHighlightStrokeColor,
595                                         //'highlightFillColor:'+gxtEl.outputFirstColorFill,
596                                         'highlightFillColor:'+gxtEl.outputFirstHighlightStrokeColor,
597                                         'visible:'+gxtEl.outputFirstVisible,
598                                         'labelColor:'+gxtEl.outputFirstColorLabel,
599                                         'draft:'+gxtEl.draft);
600                     inter.p1.setStyle(1*gxtEl.outputFirstStyle);
601                     inter.p1.traced = (gxtEl.outputFirstTrace=='false') ? false : true;
602                     inter.p2.setProperty('strokeColor:'+gxtEl.outputLastColorStroke,
603                                         'strokeWidth:'+gxtEl.outputLastStrokewidth,
604                                         //'fillColor:'+gxtEl.outputLastColorFill,
605                                         'fillColor:'+gxtEl.outputLastColorStroke,
606                                         'highlightStrokeColor:'+gxtEl.outputLastHighlightStrokeColor,
607                                         //'highlightFillColor:'+gxtEl.outputLastColorFill,
608                                         'highlightFillColor:'+gxtEl.outputLastHighlightStrokeColor,
609                                         'visible:'+gxtEl.outputLastVisible,
610                                         'labelColor:'+gxtEl.outputLastColorLabel,
611                                         'draft:'+gxtEl.draft);
612                     inter.p2.setStyle(1*gxtEl.outputLastStyle);
613                     inter.p2.traced = (gxtEl.outputLastTrace=='false') ? false : true;
614 
615                     /* if-Statement evtl. unnoetig BV*/
616                     if(gxtEl.outputFirstVisible == "false") {
617                         if(gxtEl.outputLastVisible == "false") {
618                             inter.hideElement();
619                         }
620                         else {
621                             inter.p1.hideElement();
622                         }
623                     }
624                     else {
625                         if(gxtEl.outputLastVisible == "false") {
626                             inter.p2.hideElement();
627                         }
628                     }
629                 }
630                 JXG.GeonextReader.printDebugMessage('debug',gxtEl,Data.nodeName,'OK');
631                 break;
632             case "composition":
633                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data,'data');
634                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
635                 switch(gxtEl.type) {
636                     case "210070": gxtEl.typeName = "ARROW_PARALLEL"; break;
637                     case "210080": gxtEl.typeName = "BISECTOR"; break;
638                     case "210090": gxtEl.typeName = "CIRCUMCIRCLE"; break;
639                     case "210100": gxtEl.typeName = "CIRCUMCIRCLE_CENTER"; break;
640                     case "210110": gxtEl.typeName = "MIDPOINT"; break;
641                     case "210120": gxtEl.typeName = "MIRROR_LINE"; break;
642                     case "210125": gxtEl.typeName = "MIRROR_POINT"; break;
643                     case "210130": gxtEl.typeName = "NORMAL"; break;
644                     case "210140": gxtEl.typeName = "PARALLEL"; break;
645                     case "210150": gxtEl.typeName = "PARALLELOGRAM_POINT"; break;
646                     case "210160": gxtEl.typeName = "PERPENDICULAR"; break;
647                     case "210170": gxtEl.typeName = "PERPENDICULAR_POINT"; break;
648                     case "210180": gxtEl.typeName = "ROTATION"; break; // FEHLT
649                     case "210190": gxtEl.typeName = "SECTOR"; break;
650                 }
651                 gxtEl.defEl = [];
652                 numberDefEls = 0;
653                 xmlNode = Data.getElementsByTagName('data')[0].getElementsByTagName('input');
654                 for(i=0; i<xmlNode.length; i++) {
655                     gxtEl.defEl[i] = xmlNode[i].firstChild.data;
656                     numberDefEls = i+1;
657                 }
658                 xmlNode = Data.getElementsByTagName('output')[0];
659                 gxtEl.outputId = xmlNode.getElementsByTagName('id')[0].firstChild.data;
660                 gxtEl.outputName = xmlNode.getElementsByTagName('name')[0].firstChild.data;
661                 gxtEl.outputVisible = xmlNode.getElementsByTagName('visible')[0].firstChild.data;
662                 gxtEl.outputTrace = xmlNode.getElementsByTagName('trace')[0].firstChild.data;
663 
664                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'output','output');
665                 gxtEl.outputName = xmlNode.getElementsByTagName('name')[0].firstChild.data;
666                 gxtEl.outputDash = xmlNode.getElementsByTagName('dash')[0].firstChild.data;
667                 gxtEl.outputDraft = xmlNode.getElementsByTagName('draft')[0].firstChild.data;
668                 gxtEl.outputStrokewidth = xmlNode.getElementsByTagName('strokewidth')[0].firstChild.data;
669                 //    Data.getElementsByTagName('output')[0].getElementsByTagName('strokewidth')[0].firstChild.data;
670 
671                 xmlNode = Data.getElementsByTagName('output')[0].getElementsByTagName('color')[0];
672                 gxtEl.outputColorStroke = xmlNode.getElementsByTagName('stroke')[0].firstChild.data;
673                 gxtEl.outputHighlightStrokeColor = xmlNode.getElementsByTagName('lighting')[0].firstChild.data;
674                 gxtEl.outputColorFill = xmlNode.getElementsByTagName('fill')[0].firstChild.data;
675                 gxtEl.outputColorLabel = xmlNode.getElementsByTagName('label')[0].firstChild.data;
676                 gxtEl.outputColorDraft = xmlNode.getElementsByTagName('draft')[0].firstChild.data;
677 
678                 gxtEl.defEl[0] = JXG.GeonextReader.changeOriginIds(board,gxtEl.defEl[0]);
679                 gxtEl.defEl[1] = JXG.GeonextReader.changeOriginIds(board,gxtEl.defEl[1]);
680                 gxtEl.defEl[2] = JXG.GeonextReader.changeOriginIds(board,gxtEl.defEl[2]);
681                 if(gxtEl.typeName == "MIDPOINT") {
682                     if (numberDefEls==2) {  // Midpoint of two points
683                     	board.create('midpoint', [gxtEl.defEl[0], gxtEl.defEl[1]], {name: gxtEl.outputName, id: gxtEl.outputId});
684                     } else if (numberDefEls==1) { // Midpoint of a line
685                     	board.create('midpoint', [gxtEl.defEl[0]], {name: gxtEl.outputName, id: gxtEl.outputId});
686                     }
687                 }
688                 else if(gxtEl.typeName == "NORMAL") {
689                     //board.addNormal(gxtEl.defEl[1], gxtEl.defEl[0], gxtEl.outputId, gxtEl.outputName);
690                     board.create('normal', [gxtEl.defEl[1], gxtEl.defEl[0]], {'id': gxtEl.outputId, name: gxtEl.outputName});
691                 }
692                 else if(gxtEl.typeName == "PARALLEL") {
693                     board.create('parallel', [gxtEl.defEl[1], gxtEl.defEl[0]], {'id': gxtEl.outputId, name: gxtEl.outputName});
694                 }
695                 else if(gxtEl.typeName == "CIRCUMCIRCLE") {
696                     umkreisId = Data.getElementsByTagName('output')[1].getElementsByTagName('id')[0].firstChild.data;
697                     umkreisName = Data.getElementsByTagName('output')[1].getElementsByTagName('name')[0].firstChild.data;
698                     board.create('circumcircle', [gxtEl.defEl[0], gxtEl.defEl[1], gxtEl.defEl[2]], {name: [gxtEl.outputName, umkreisName], id: [gxtEl.outputId, umkreisId]});
699                 }
700                 else if(gxtEl.typeName == "CIRCUMCIRCLE_CENTER") {
701                     board.create('circumcirclemidpoint', [gxtEl.defEl[0], gxtEl.defEl[1], gxtEl.defEl[2]], {id: gxtEl.outputId, name: gxtEl.outputName});
702                 }
703                 else if(gxtEl.typeName == "BISECTOR") {
704                     board.create('bisector', [gxtEl.defEl[0], gxtEl.defEl[1], gxtEl.defEl[2]], {id: gxtEl.outputId, name: gxtEl.outputName});
705                 }
706                 else if(gxtEl.typeName == "MIRROR_LINE") {
707                     board.create('reflection', [gxtEl.defEl[1], gxtEl.defEl[0]], {id: gxtEl.outputId, name: gxtEl.outputName});
708                 }
709                 else if(gxtEl.typeName == "MIRROR_POINT") {
710                     // Spaeter: Rotation --> Winkel statt Math.PI
711                     board.create('mirrorpoint', [gxtEl.defEl[0], gxtEl.defEl[1]], {name: gxtEl.outputName, id: gxtEl.outputId});
712                 }
713                 else if(gxtEl.typeName == "PARALLELOGRAM_POINT") {
714                     if (gxtEl.defEl.length==2) { // line, point
715                         board.create('parallelpoint', [JXG.getReference(board, gxtEl.defEl[0]).point1,
716                                                JXG.getReference(board, gxtEl.defEl[0]).point2,
717                                                gxtEl.defEl[1]], {id: gxtEl.outputId, name: gxtEl.outputName});
718                     } else {  // point, point, point
719                         board.create('parallelpoint', [gxtEl.defEl[0], gxtEl.defEl[1], gxtEl.defEl[2]], {id: gxtEl.outputId, name: gxtEl.outputName});
720                     }
721                 }
722                 else if(gxtEl.typeName == "SECTOR") {
723                     //JXG.GeonextReader.parseImage(board,Data.getElementsByTagName('image')[0],board.options.layer['sector']);
724                     for(i=0; i<Data.getElementsByTagName('output').length; i++) {
725                         xmlNode = Data.getElementsByTagName('output')[i];
726                         defEl[i] = xmlNode.getElementsByTagName('id')[0].firstChild.data;
727                         defEl[i] = JXG.GeonextReader.changeOriginIds(board,defEl[i]);
728                         defElN[i] = xmlNode.getElementsByTagName('name')[0];
729                         defElV[i] = xmlNode.getElementsByTagName('visible')[0].firstChild.data;
730                         defElT[i] = xmlNode.getElementsByTagName('trace')[0].firstChild.data;
731                         defElD[i] = xmlNode.getElementsByTagName('dash')[0].firstChild.data;
732                         defElDr[i] = xmlNode.getElementsByTagName('draft')[0].firstChild.data;
733                         defElSW[i] = xmlNode.getElementsByTagName('strokewidth')[0].firstChild.data;
734 
735                         xmlNode = Data.getElementsByTagName('output')[i].getElementsByTagName('color')[0];
736                         defElColStr[i] = xmlNode.getElementsByTagName('stroke')[0].firstChild.data;
737                         defElHColStr[i] = xmlNode.getElementsByTagName('lighting')[0].firstChild.data;
738                         defElColF[i] = xmlNode.getElementsByTagName('fill')[0].firstChild.data;
739                         defElColL[i] = xmlNode.getElementsByTagName('label')[0].firstChild.data;
740                     }
741                     /*
742                     el = new JXG.Sector(board, gxtEl.defEl[0],
743                                            gxtEl.defEl[1], gxtEl.defEl[2],
744                                            [defEl[0], defEl[1], defEl[2], defEl[3]],
745                                            [defElN[0].firstChild.data, defElN[1].firstChild.data, defElN[2].firstChild.data,
746                                                defElN[3].firstChild.data],
747                                            gxtEl.id);
748                     // Sector hat keine eigenen Eigenschaften
749                     //el.setProperty('fillColor:'+defElColF[0],'highlightFillColor:'+defElColF[0], 'strokeColor:none');
750                     */
751                     el = board.create('sector', [gxtEl.defEl[0],gxtEl.defEl[1],gxtEl.defEl[2]], 
752                                             {id:defEl[0], name: defElN[0].firstChild.data});
753                     /* Eigenschaften des Kreisbogens */
754                     arcId = defEl[0];
755                     board.objects[arcId].setProperty('strokeColor:'+defElColStr[0],
756                                                      'strokeWidth:'+defElSW[0],
757                                                      'fillColor:'+defElColF[0],
758                                                      'highlightStrokeColor:'+defElHColStr[0],
759                                                      'highlightFillColor:'+defElColF[0],
760                                                      'visible:'+defElV[0],
761                                                      'dash:'+defElD[0],
762                                                      'draft:'+defElDr[0]);
763                     board.objects[arcId].traced = (defElT[0]=='false') ? false : true;
764                     gxtEl.firstArrow = Data.getElementsByTagName('output')[0].getElementsByTagName('firstarrow')[0].firstChild.data;
765                     gxtEl.lastArrow = Data.getElementsByTagName('output')[0].getElementsByTagName('lastarrow')[0].firstChild.data;
766                     gxtEl.firstArrow = (gxtEl.firstArrow=='false') ? false : true;
767                     gxtEl.lastArrow = (gxtEl.lastArrow=='false') ? false : true;
768                     board.objects[arcId].setArrow(gxtEl.firstArrow,gxtEl.lastArrow);
769                     /* Eigenschaften des Endpunkts */
770                     /*
771                     pointId = board.objects[gxtEl.defEl[1]].id; //defEl[1];
772                     gxtEl.fixed = Data.getElementsByTagName('output')[1].getElementsByTagName('fix')[0].firstChild.data;
773                     board.objects[pointId].setProperty('strokeColor:'+defElColStr[1],
774                                                        'strokeWidth:'+defElSW[1],
775                                                        //'fillColor:'+defElColF[1],
776                                                        'fillColor:'+defElColStr[1],
777                                                        'highlightStrokeColor:'+defElHColStr[1],
778                                                        //'highlightFillColor:'+defElColF[1],
779                                                        'highlightFillColor:'+defElHColStr[1],
780                                                        'visible:'+defElV[1],
781                                                        'fixed:'+gxtEl.fixed,
782                                                        'labelColor:'+defElColL[1],
783                                                        'draft:'+defElDr[1]);
784                     gxtEl.style = Data.getElementsByTagName('output')[1].getElementsByTagName('style')[0].firstChild.data;
785                     board.objects[pointId].setStyle(1*gxtEl.style);
786                     board.objects[pointId].traced = (defElT[1]=='false') ? false : true;
787                     */
788                     /* Eigenschaften der ersten Linie */
789                     /*
790                     line1Id = defEl[2];
791 
792                     xmlNode = Data.getElementsByTagName('output')[2].getElementsByTagName('straight')[0];
793                     gxtEl.straightFirst = xmlNode.getElementsByTagName('first')[0].firstChild.data;
794                     gxtEl.straightLast = xmlNode.getElementsByTagName('last')[0].firstChild.data;
795                     gxtEl.straightFirst = (gxtEl.straightFirst=='false') ? false : true;
796                     gxtEl.straightLast = (gxtEl.straightLast=='false') ? false : true;
797                     board.objects[line1Id].setStraight(gxtEl.straightFirst, gxtEl.straightLast);
798                     board.objects[line1Id].setProperty('strokeColor:'+defElColStr[2],
799                                                        'strokeWidth:'+defElSW[2],
800                                                        'fillColor:'+defElColF[2],
801                                                        'highlightStrokeColor:'+defElHColStr[2],
802                                                        'highlightFillColor:'+defElColF[2],
803                                                        'visible:'+defElV[2],
804                                                        'dash:'+defElD[2],
805                                                        'draft:'+defElDr[2]);
806                     board.objects[line1Id].traced = (defElT[2]=='false') ? false : true;
807                     */
808                     /* Eigenschaften der zweiten Linie */
809                     /*
810                     line2Id = defEl[3];
811                     xmlNode = Data.getElementsByTagName('output')[3].getElementsByTagName('straight')[0];
812                     gxtEl.straightFirst = xmlNode.getElementsByTagName('first')[0].firstChild.data;
813                     gxtEl.straightLast = xmlNode.getElementsByTagName('last')[0].firstChild.data;
814                     gxtEl.straightFirst = (gxtEl.straightFirst=='false') ? false : true;
815                     gxtEl.straightLast = (gxtEl.straightLast=='false') ? false : true;
816                     board.objects[line2Id].setStraight(gxtEl.straightFirst, gxtEl.straightLast);
817                     board.objects[line2Id].setProperty('strokeColor:'+defElColStr[3],
818                                                        'strokeWidth:'+defElSW[3],
819                                                        'fillColor:'+defElColF[3],
820                                                        'highlightStrokeColor:'+defElHColStr[3],
821                                                        'highlightFillColor:'+defElColF[3],
822                                                        'visible:'+defElV[3],
823                                                        'dash:'+defElD[3],
824                                                        'draft:'+defElDr[3]);
825                     board.objects[line2Id].traced = (defElT[3]=='false') ? false : true;
826                     */
827                 }
828                 else if(gxtEl.typeName == "PERPENDICULAR") {
829                     for(i=0; i<Data.getElementsByTagName('output').length; i++) {
830                         xmlNode = Data.getElementsByTagName('output')[i];
831                         defEl[i] = xmlNode.getElementsByTagName('id')[0].firstChild.data;
832                         defEl[i] = JXG.GeonextReader.changeOriginIds(board,defEl[i]);
833                         defElN[i] = xmlNode.getElementsByTagName('name')[0];
834                         defElV[i] = xmlNode.getElementsByTagName('visible')[0].firstChild.data;
835                         defElT[i] = xmlNode.getElementsByTagName('trace')[0].firstChild.data;
836                         defElD[i] = xmlNode.getElementsByTagName('dash')[0].firstChild.data;
837                         defElDr[i] = xmlNode.getElementsByTagName('draft')[0].firstChild.data;
838                         defElSW[i] = xmlNode.getElementsByTagName('strokewidth')[0].firstChild.data;
839                         xmlNode = Data.getElementsByTagName('output')[i].getElementsByTagName('color')[0];
840                         defElColStr[i] = xmlNode.getElementsByTagName('stroke')[0].firstChild.data;
841                         defElHColStr[i] = xmlNode.getElementsByTagName('lighting')[0].firstChild.data;
842                         defElColF[i] = xmlNode.getElementsByTagName('fill')[0].firstChild.data;
843                         defElColL[i] = xmlNode.getElementsByTagName('label')[0].firstChild.data;
844                     }
845                     gxtEl.outputFixed = Data.getElementsByTagName('output')[0].getElementsByTagName('fix')[0].firstChild.data;
846                     gxtEl.outputStyle = Data.getElementsByTagName('output')[0].getElementsByTagName('style')[0].firstChild.data;
847 
848                     board.create('perpendicular', [gxtEl.defEl[1], gxtEl.defEl[0]],
849                                         {name: [defElN[1].firstChild.data, defElN[0].firstChild.data],
850                                          id:[defEl[1], defEl[0]]});
851                     /* Eigenschaften des Lotfusspunkts */
852                     pid = defEl[0];
853                     board.objects[pid].setProperty('strokeColor:'+defElColStr[0],
854                                                                           'strokeWidth:'+defElSW[0],
855                                                                           //'fillColor:'+defElColF[0],
856                                                                           'fillColor:'+defElColStr[0],
857                                                                           'highlightStrokeColor:'+defElHColStr[0],
858                                                                           //'highlightFillColor:'+defElColF[0],
859                                                                           'highlightFillColor:'+defElHColStr[0],
860                                                                           'visible:'+defElV[0],
861                                                                           'fixed:'+gxtEl.outputFixed,
862                                                                           'labelColor:'+defElColL[0],
863                                                                           'draft:'+defElDr[0]);
864                     board.objects[pid].setStyle(1*gxtEl.outputStyle);
865                     board.objects[pid].traced = (defElT[0]=='false') ? false : true;
866                     /* Eigenschaften der Lotstrecke */
867                     lid = defEl[1];
868                     board.objects[lid].setProperty('strokeColor:'+defElColStr[1],
869                                                                           'strokeWidth:'+defElSW[1],
870                                                                           'fillColor:'+defElColF[1],
871                                                                           'highlightStrokeColor:'+defElHColStr[1],
872                                                                           'highlightFillColor:'+defElColF[1],
873                                                                           'visible:'+defElV[1],
874                                                                           'dash:'+defElD[1],
875                                                                           'draft:'+defElDr[1]);
876                     board.objects[lid].traced = (defElT[1]=='false') ? false : true;
877                     xmlNode = Data.getElementsByTagName('output')[1].getElementsByTagName('straight')[0];
878                     strFir = xmlNode.getElementsByTagName('first')[0].firstChild.data;
879                     strLas = xmlNode.getElementsByTagName('last')[0].firstChild.data;                  
880                     strFir = (strFir=='false') ? false : true;
881                     strLas = (strLas=='false') ? false : true;
882                     board.objects[lid].setStraight(strFir, strLas);                                                                          
883                     board.objects[pid].setStyle(1*gxtEl.outputStyle);
884                     board.objects[pid].traced = (defElT[1]=='false') ? false : true;                    
885                 }
886                 else if(gxtEl.typeName == "ARROW_PARALLEL") {
887                     for(i=0; i<Data.getElementsByTagName('output').length; i++) {
888                         xmlNode = Data.getElementsByTagName('output')[i];
889                         defEl[i] = xmlNode.getElementsByTagName('id')[0].firstChild.data;
890                         defEl[i] = JXG.GeonextReader.changeOriginIds(board,defEl[i]);
891                         defElN[i] = xmlNode.getElementsByTagName('name')[0];
892                         defElV[i] = xmlNode.getElementsByTagName('visible')[0].firstChild.data;
893                         defElT[i] = xmlNode.getElementsByTagName('trace')[0].firstChild.data;
894                         defElD[i] = xmlNode.getElementsByTagName('dash')[0].firstChild.data;
895                         defElDr[i] = xmlNode.getElementsByTagName('draft')[0].firstChild.data;
896                         defElSW[i] = xmlNode.getElementsByTagName('strokewidth')[0].firstChild.data;
897                         xmlNode = Data.getElementsByTagName('output')[i].getElementsByTagName('color')[0];
898                         defElColStr[i] = xmlNode.getElementsByTagName('stroke')[0].firstChild.data;
899                         defElHColStr[i] = xmlNode.getElementsByTagName('lighting')[0].firstChild.data;
900                         defElColF[i] = xmlNode.getElementsByTagName('fill')[0].firstChild.data;
901                         defElColL[i] = xmlNode.getElementsByTagName('label')[0].firstChild.data;
902                     }
903                     gxtEl.outputFixed = Data.getElementsByTagName('output')[1].getElementsByTagName('fix')[0].firstChild.data;
904                     gxtEl.outputStyle = Data.getElementsByTagName('output')[1].getElementsByTagName('style')[0].firstChild.data;
905 
906                     board.create('arrowparallel', [gxtEl.defEl[1], gxtEl.defEl[0]], {id: [defEl[0], defEl[1]], name: [defElN[0].firstChild.data, defElN[1].firstChild.data]});
907 
908                     /* Eigenschaften des erzeugten Arrows */
909                     aid = defEl[0];
910                     board.objects[aid].setProperty('strokeColor:'+defElColStr[0],
911                                                                           'strokeWidth:'+defElSW[0],
912                                                                           'fillColor:'+defElColF[0],
913                                                                           'highlightStrokeColor:'+defElHColStr[0],
914                                                                           'highlightFillColor:'+defElColF[0],
915                                                                           'visible:'+defElV[0],
916                                                                           'dash:'+defElD[0],
917                                                                           'draft:'+defElDr[0]);
918                     board.objects[aid].traced = (defElT[0]=='false') ? false : true;
919                     /* Eigenschaften des Endpunkts */
920                     pid = defEl[1];
921                     board.objects[pid].setProperty('strokeColor:'+defElColStr[1],
922                                                                           'strokeWidth:'+defElSW[1],
923                                                                           //'fillColor:'+defElColF[1],
924                                                                           'fillColor:'+defElColStr[1],
925                                                                           'highlightStrokeColor:'+defElHColStr[1],
926                                                                           //'highlightFillColor:'+defElColF[1],
927                                                                           'highlightFillColor:'+defElHColStr[1],
928                                                                           'visible:'+defElV[1],
929                                                                           'fixed:'+gxtEl.outputFixed,
930                                                                           'labelColor:'+defElColL[1],
931                                                                           'draft:'+defElDr[1]);
932                 }
933                 else if(gxtEl.typeName == "PERPENDICULAR_POINT") {
934                     board.create('perpendicularpoint', [gxtEl.defEl[1], gxtEl.defEl[0]], {name: gxtEl.outputName, id: gxtEl.outputId});
935                 }
936                 else {
937                     throw new Error("JSXGraph: GEONExT-Element " + gxtEl.typeName + ' not yet implemented');
938                 }
939                 /* noch die Eigenschaften der uebrigen Elemente setzen */
940                 if(gxtEl.typeName == "MIDPOINT" || gxtEl.typeName == "MIRROR_LINE" ||
941                    gxtEl.typeName == "CIRCUMCIRCLE_CENTER" || gxtEl.typeName == "PERPENDICULAR_POINT" ||
942                    gxtEl.typeName == "MIRROR_POINT" || gxtEl.typeName == "PARALLELOGRAM_POINT") { // hier wird jeweils ein Punkt angelegt
943                     gxtEl.outputFixed = Data.getElementsByTagName('output')[0].getElementsByTagName('fix')[0].firstChild.data;
944                     gxtEl.outputStyle = Data.getElementsByTagName('output')[0].getElementsByTagName('style')[0].firstChild.data;
945                     board.objects[gxtEl.outputId].setProperty('strokeColor:'+gxtEl.outputColorStroke,
946                                                                        'strokeWidth:'+gxtEl.outputStrokewidth,
947                                                                        //'fillColor:'+gxtEl.outputColorFill,
948                                                                        'fillColor:'+gxtEl.outputColorStroke,
949                                                                        'highlightStrokeColor:'+gxtEl.outputHighlightStrokeColor,
950                                                                        //'highlightFillColor:'+gxtEl.outputColorFill,
951                                                                        'highlightFillColor:'+gxtEl.outputHighlightStrokeColor,
952                                                                        'visible:'+gxtEl.outputVisible,
953                                                                        'fixed:'+gxtEl.outputFixed,
954                                                                        'labelColor:'+gxtEl.outputColorLabel,
955                                                                        'draft:'+gxtEl.outputDraft);
956                     board.objects[gxtEl.outputId].setStyle(1*gxtEl.outputStyle);
957                     board.objects[gxtEl.outputId].traced = (gxtEl.outputTrace=='false') ? false : true;
958                 }
959                 else if(gxtEl.typeName == "BISECTOR" || gxtEl.typeName == "NORMAL" ||
960                         gxtEl.typeName == "PARALLEL") { // hier wird jeweils eine Linie angelegt
961                     xmlNode = Data.getElementsByTagName('output')[0].getElementsByTagName('straight')[0];
962                     gxtEl.straightFirst = xmlNode.getElementsByTagName('first')[0].firstChild.data;
963                     gxtEl.straightLast = xmlNode.getElementsByTagName('last')[0].firstChild.data;
964                     gxtEl.straightFirst = (gxtEl.straightFirst=='false') ? false : true;
965                     gxtEl.straightLast = (gxtEl.straightLast=='false') ? false : true;
966                     board.objects[gxtEl.outputId].setStraight(gxtEl.straightFirst, gxtEl.straightLast);
967                     board.objects[gxtEl.outputId].setProperty('strokeColor:'+gxtEl.outputColorStroke,
968                                                                        'strokeWidth:'+gxtEl.outputStrokewidth,
969                                                                        'fillColor:'+gxtEl.outputColorFill,
970                                                                        'highlightStrokeColor:'+gxtEl.outputHighlightStrokeColor,
971                                                                        'highlightFillColor:'+gxtEl.outputColorFill,
972                                                                        'visible:'+gxtEl.outputVisible,
973                                                                        'dash:'+gxtEl.outputDash,
974                                                                        'draft:'+gxtEl.outputDraft);
975                     board.objects[gxtEl.outputId].traced = (gxtEl.outputTrace=='false') ? false : true;
976                 }
977                 else if(gxtEl.typeName == "CIRCUMCIRCLE") {
978                     for(i=0; i<Data.getElementsByTagName('output').length; i++) {
979                         xmlNode = Data.getElementsByTagName('output')[i];
980                         defEl[i] = xmlNode.getElementsByTagName('id')[0].firstChild.data;
981                         defEl[i] = JXG.GeonextReader.changeOriginIds(board,defEl[i]);
982                         defElN[i] = xmlNode.getElementsByTagName('name')[0];
983                         defElV[i] = xmlNode.getElementsByTagName('visible')[0].firstChild.data;
984                         defElT[i] = xmlNode.getElementsByTagName('trace')[0].firstChild.data;
985                         defElD[i] = xmlNode.getElementsByTagName('dash')[0].firstChild.data;
986                         defElDr[i] = xmlNode.getElementsByTagName('draft')[0].firstChild.data;
987                         defElSW[i] = xmlNode.getElementsByTagName('strokewidth')[0].firstChild.data;
988                         xmlNode = Data.getElementsByTagName('output')[i].getElementsByTagName('color')[0];
989                         defElColStr[i] = xmlNode.getElementsByTagName('stroke')[0].firstChild.data;
990                         defElHColStr[i] = xmlNode.getElementsByTagName('lighting')[0].firstChild.data;
991                         defElColF[i] = xmlNode.getElementsByTagName('fill')[0].firstChild.data;
992                         defElColL[i] = xmlNode.getElementsByTagName('label')[0].firstChild.data;
993                     }
994                     gxtEl.outputFixed = Data.getElementsByTagName('output')[0].getElementsByTagName('fix')[0].firstChild.data;
995                     gxtEl.outputStyle = Data.getElementsByTagName('output')[0].getElementsByTagName('style')[0].firstChild.data;
996                     /* Eigenschaften des Umkreismittelpunkts */
997                     pid = defEl[0];
998                     board.objects[pid].setProperty('strokeColor:'+defElColStr[0],
999                                                                           'strokeWidth:'+defElSW[0],
1000                                                                           //'fillColor:'+defElColF[0],
1001                                                                           'fillColor:'+defElColStr[0],
1002                                                                           'highlightStrokeColor:'+defElHColStr[0],
1003                                                                           //'highlightFillColor:'+defElColF[0],
1004                                                                           'highlightFillColor:'+defElHColStr[0],
1005                                                                           'visible:'+defElV[0],
1006                                                                           'fixed:'+gxtEl.outputFixed,
1007                                                                           'labelColor:'+defElColL[0],
1008                                                                           'draft:'+defElDr[0]);
1009                     board.objects[pid].setStyle(1*gxtEl.outputStyle);
1010                     board.objects[pid].traced = (defElT[0]=='false') ? false : true;
1011                     /* Eigenschaften des Umkreises */
1012                     cid = defEl[1];
1013                     board.objects[cid].setProperty('strokeColor:'+defElColStr[1],
1014                                                                           'strokeWidth:'+defElSW[1],
1015                                                                           'fillColor:'+defElColF[1],
1016                                                                           'highlightStrokeColor:'+defElHColStr[1],
1017                                                                           'highlightFillColor:'+defElColF[1],
1018                                                                           'visible:'+defElV[1],
1019                                                                           'dash:'+defElD[1],
1020                                                                           'draft:'+defElDr[1]);
1021                     board.objects[cid].traced = (defElT[1]=='false') ? false : true;
1022                 }
1023                 if (board.isSuspendedUpdate) {
1024                     board.unsuspendUpdate().suspendUpdate();
1025                 }
1026                 // "PERPENDICULAR" und "SECTOR" werden direkt im oberen if erledigt
1027                 JXG.GeonextReader.printDebugMessage('debug',gxtEl,Data.nodeName,'OK');
1028                 break;
1029             case "polygon":
1030                 gxtEl = JXG.GeonextReader.colorProperties(gxtEl, Data);
1031                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
1032                 gxtEl.dataVertex = [];
1033                 for(i=0; i<Data.getElementsByTagName('data')[0].getElementsByTagName('vertex').length; i++) {
1034                     gxtEl.dataVertex[i] = Data.getElementsByTagName('data')[0].getElementsByTagName('vertex')[i].firstChild.data;
1035                     gxtEl.dataVertex[i] = JXG.GeonextReader.changeOriginIds(board,gxtEl.dataVertex[i]);
1036                 }
1037                 gxtEl.border = [];
1038                 for(i=0; i<Data.getElementsByTagName('border').length; i++) {
1039                     gxtEl.border[i] = {};
1040                     xmlNode = Data.getElementsByTagName('border')[i];
1041                     gxtEl.border[i].id = xmlNode.getElementsByTagName('id')[0].firstChild.data;
1042                     gxtEl.border[i].name = xmlNode.getElementsByTagName('name')[0].firstChild.data;
1043                     gxtEl.border[i].straightFirst =
1044                         xmlNode.getElementsByTagName('straight')[0].getElementsByTagName('first')[0].firstChild.data;
1045                     gxtEl.border[i].straightLast =
1046                         xmlNode.getElementsByTagName('straight')[0].getElementsByTagName('last')[0].firstChild.data;
1047                     gxtEl.border[i].straightFirst = (gxtEl.border[i].straightFirst=='false') ? false : true;
1048                     gxtEl.border[i].straightLast = (gxtEl.border[i].straightLast=='false') ? false : true;
1049                     gxtEl.border[i].strokewidth = xmlNode.getElementsByTagName('strokewidth')[0].firstChild.data;
1050                     gxtEl.border[i].dash = xmlNode.getElementsByTagName('dash')[0].firstChild.data;
1051                     gxtEl.border[i].visible = xmlNode.getElementsByTagName('visible')[0].firstChild.data;
1052                     gxtEl.border[i].draft = xmlNode.getElementsByTagName('draft')[0].firstChild.data;
1053                     gxtEl.border[i].trace = xmlNode.getElementsByTagName('trace')[0].firstChild.data;
1054 
1055                     xmlNode = Data.getElementsByTagName('border')[i].getElementsByTagName('color')[0];
1056                     gxtEl.border[i].colorStroke = xmlNode.getElementsByTagName('stroke')[0].firstChild.data;
1057                     gxtEl.border[i].highlightStrokeColor = xmlNode.getElementsByTagName('lighting')[0].firstChild.data;
1058                     gxtEl.border[i].colorFill = xmlNode.getElementsByTagName('fill')[0].firstChild.data;
1059                     gxtEl.border[i].colorLabel = xmlNode.getElementsByTagName('label')[0].firstChild.data;
1060                     gxtEl.border[i].colorDraft = xmlNode.getElementsByTagName('draft')[0].firstChild.data;
1061                 }
1062                 //JXG.GeonextReader.parseImage(board,Data.getElementsByTagName('image')[0],board.options.layer['polygon']);
1063                 p = new JXG.Polygon(board, gxtEl.dataVertex, gxtEl.border, gxtEl.id, gxtEl.name, true,true,true);
1064                 p.setProperty('strokeColor:'+gxtEl.colorStroke,'strokeWidth:'+gxtEl.strokewidth,
1065                               'fillColor:'+gxtEl.colorFill,'highlightStrokeColor:'+gxtEl.highlightStrokeColor,
1066                               'highlightFillColor:'+gxtEl.colorFill,'labelColor:'+gxtEl.colorLabel,
1067                               'draft:'+gxtEl.draft,'trace:'+gxtEl.trace,'visible:true');
1068                 // to emulate the geonext behaviour on invisible polygones
1069                 if(!gxtEl.visible) {
1070                     p.setProperty('fillColor:none','highlightFillColor:none');
1071                 }
1072                 for(i=0; i<p.borders.length; i++) {
1073                     p.borders[i].setStraight(gxtEl.border[i].straightFirst, gxtEl.border[i].straightLast);
1074                     p.borders[i].setProperty('strokeColor:'+gxtEl.border[i].colorStroke,
1075                                              'strokeWidth:'+gxtEl.border[i].strokewidth,
1076                                              'fillColor:'+gxtEl.border[i].colorFill,
1077                                              'highlightStrokeColor:'+gxtEl.border[i].highlightStrokeColor,
1078                                              'highlightFillColor:'+gxtEl.border[i].colorFill,
1079                                              'visible:'+gxtEl.border[i].visible,
1080                                              'dash:'+gxtEl.border[i].dash,'labelColor:'+gxtEl.border[i].colorLabel,
1081                                              'draft:'+gxtEl.border[i].draft,'trace:'+gxtEl.border[i].trace);
1082                 }
1083                 JXG.GeonextReader.printDebugMessage('debug',gxtEl,Data.nodeName,'OK');
1084                 break;
1085             case "graph":
1086                 gxtEl = JXG.GeonextReader.colorProperties(gxtEl, Data);
1087                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
1088                 gxtEl.funct = Data.getElementsByTagName('data')[0].getElementsByTagName('function')[0].firstChild.data;
1089                 //JXG.GeonextReader.parseImage(board,Data.getElementsByTagName('image')[0],board.options.layer['curve']);
1090                 c = new JXG.Curve(board, ['x','x',gxtEl.funct], gxtEl.id, gxtEl.name);
1091                 JXG.GeonextReader.printDebugMessage('debug',gxtEl,Data.nodeName,'OK');
1092                 /*
1093                  * Ignore fillcolor attribute
1094                  * g.setProperty('strokeColor:'+gxtEl.colorStroke,'strokeWidth:'+gxtEl.strokewidth,'fillColor:'+gxtEl.colorFill,
1095                               'highlightStrokeColor:'+gxtEl.highlightStrokeColor);*/
1096                 c.setProperty('strokeColor:'+gxtEl.colorStroke,'strokeWidth:'+gxtEl.strokewidth,'fillColor:none',
1097                               'highlightStrokeColor:'+gxtEl.highlightStrokeColor);
1098 
1099                 break;
1100             case "arrow":
1101                 gxtEl = JXG.GeonextReader.colorProperties(gxtEl, Data);
1102                 gxtEl = JXG.GeonextReader.boardProperties(gxtEl, Data);
1103                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
1104                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'data');
1105                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'straight','straight');
1106                 gxtEl = JXG.GeonextReader.visualProperties(gxtEl, Data);
1107                 gxtEl.first = JXG.GeonextReader.changeOriginIds(board,gxtEl.first);
1108                 gxtEl.last = JXG.GeonextReader.changeOriginIds(board,gxtEl.last);
1109                 l = new JXG.Line(board, gxtEl.first, gxtEl.last, gxtEl.id, gxtEl.name);
1110                 l.setProperty('strokeColor:'+gxtEl.colorStroke,'strokeWidth:'+gxtEl.strokewidth,
1111                               'fillColor:'+gxtEl.colorFill,'highlightStrokeColor:'+gxtEl.highlightStrokeColor,
1112                               'highlightFillColor:'+gxtEl.colorFill,'labelColor:'+gxtEl.colorLabel,
1113                               'visible:'+gxtEl.visible, 'dash:'+gxtEl.dash, 'draft:'+gxtEl.draft);
1114                 l.setStraight(false,false);
1115                 l.setArrow(false,true);
1116                 l.traced = (gxtEl.trace=='false') ? false : true;
1117                 JXG.GeonextReader.printDebugMessage('debug',l,Data.nodeName,'OK');
1118                 break;
1119             case "arc":
1120                 gxtEl = JXG.GeonextReader.colorProperties(gxtEl, Data);
1121                 gxtEl = JXG.GeonextReader.visualProperties(gxtEl, Data);
1122                 gxtEl = JXG.GeonextReader.boardProperties(gxtEl, Data);
1123                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
1124                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'data');
1125 
1126                 gxtEl.firstArrow = Data.getElementsByTagName('firstarrow')[0].firstChild.data;
1127                 gxtEl.lastArrow = Data.getElementsByTagName('lastarrow')[0].firstChild.data;
1128                 //JXG.GeonextReader.parseImage(board,Data.getElementsByTagName('image')[0],board.options.layer['arc']);
1129                 gxtEl.midpoint = JXG.GeonextReader.changeOriginIds(board,gxtEl.midpoint);
1130                 gxtEl.angle = JXG.GeonextReader.changeOriginIds(board,gxtEl.angle);
1131                 gxtEl.radius = JXG.GeonextReader.changeOriginIds(board,gxtEl.radius);
1132                 /*
1133                 c = new JXG.Arc(board, gxtEl.midpoint, gxtEl.radius, gxtEl.angle,
1134                                 gxtEl.id, gxtEl.name);
1135                 c.setProperty('strokeColor:'+gxtEl.colorStroke,'strokeWidth:'+gxtEl.strokewidth,
1136                               'fillColor:'+gxtEl.colorFill,'highlightStrokeColor:'+gxtEl.highlightStrokeColor,
1137                               'highlightFillColor:'+gxtEl.colorFill,'labelColor:'+gxtEl.colorLabel,
1138                               'visible:'+gxtEl.visible, 'dash:'+gxtEl.dash, 'draft:'+gxtEl.draft);
1139                 c.traced = (gxtEl.trace=='false') ? false : true;
1140                 gxtEl.firstArrow = (gxtEl.firstArrow=='false') ? false : true;
1141                 gxtEl.lastArrow = (gxtEl.lastArrow=='false') ? false : true;
1142                 c.setArrow(gxtEl.firstArrow,gxtEl.lastArrow);
1143                 */
1144                 c = board.create('arc', [gxtEl.midpoint, gxtEl.radius, gxtEl.angle], {id:gxtEl.id, name:gxtEl.name});
1145                 c.setProperty('strokeColor:'+gxtEl.colorStroke,'strokeWidth:'+gxtEl.strokewidth,
1146                               'fillColor:'+gxtEl.colorFill,'highlightStrokeColor:'+gxtEl.highlightStrokeColor,
1147                               'highlightFillColor:'+gxtEl.colorFill,'labelColor:'+gxtEl.colorLabel,
1148                               'visible:'+gxtEl.visible, 'dash:'+gxtEl.dash, 'draft:'+gxtEl.draft,
1149                               'trace:'+gxtEl.trace, 'firstArrow:'+gxtEl.firstArrow, 'lastArrow:'+gxtEl.lastArrow);
1150                 JXG.GeonextReader.printDebugMessage('debug',c,Data.nodeName,'OK');
1151                 break;
1152             case "angle":
1153                 gxtEl = JXG.GeonextReader.boardProperties(gxtEl, Data);
1154                 gxtEl = JXG.GeonextReader.colorProperties(gxtEl, Data);
1155                 gxtEl = JXG.GeonextReader.visualProperties(gxtEl, Data);
1156                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
1157                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'data');
1158                 //gxtEl.txt = JXG.GeonextReader.subtreeToString(Data.getElementsByTagName('text')[0]).firstChild.data;
1159                 try {
1160                     gxtEl.txt = Data.getElementsByTagName('text')[0].firstChild.data;
1161                 } catch (e) {
1162                     gxtEl.txt = '';
1163                 }
1164                 //c = new JXG.Angle(board, gxtEl.first, gxtEl.middle, gxtEl.last, gxtEl.radius, gxtEl.txt, gxtEl.id, gxtEl.name);
1165                 c = board.create('angle',[gxtEl.first, gxtEl.middle, gxtEl.last],{radius:gxtEl.radius, text:gxtEl.txt, id:gxtEl.id, name:gxtEl.name});
1166                 c.setProperty('strokeColor:'+gxtEl.colorStroke,'strokeWidth:'+gxtEl.strokewidth,
1167                               'fillColor:'+gxtEl.colorFill,'highlightStrokeColor:'+gxtEl.highlightStrokeColor,
1168                               'highlightFillColor:'+gxtEl.colorFill,'labelColor:'+gxtEl.colorLabel,
1169                               'visible:'+gxtEl.visible, 'dash:'+gxtEl.dash /*, 'draft:'+gxtEl.draft*/);
1170                 JXG.GeonextReader.printDebugMessage('debug',gxtEl,Data.nodeName,'OK');
1171                 break;
1172             case "text":
1173                 if (gxtEl.id.match(/oldVersion/)) break;
1174                 gxtEl = JXG.GeonextReader.boardProperties(gxtEl, Data);
1175                 gxtEl = JXG.GeonextReader.colorProperties(gxtEl, Data);
1176                 gxtEl = JXG.GeonextReader.visualProperties(gxtEl, Data);
1177                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
1178 
1179                 gxtEl = JXG.GeonextReader.readNodes(gxtEl, Data, 'data');
1180                 gxtEl.mpStr = JXG.GeonextReader.subtreeToString(Data.getElementsByTagName('data')[0].getElementsByTagName('mp')[0]);
1181                 gxtEl.mpStr = gxtEl.mpStr.replace(/<\/?mp>/g,'');
1182                 try{
1183                     if (Data.getElementsByTagName('data')[0].getElementsByTagName('parent')[0].firstChild) {
1184                         gxtEl.parent = Data.getElementsByTagName('data')[0].getElementsByTagName('parent')[0].firstChild.data;
1185                     }
1186                 } catch (e) { /*alert("parent in text not found");*/ } // This maybe empty
1187                 gxtEl.condition = Data.getElementsByTagName('condition')[0].firstChild.data;
1188                 gxtEl.content = Data.getElementsByTagName('content')[0].firstChild.data;
1189                 gxtEl.fix = Data.getElementsByTagName('fix')[0].firstChild.data;
1190                 // not used gxtEl.digits = Data.getElementsByTagName('cs')[0].firstChild.data;
1191                 gxtEl.autodigits = Data.getElementsByTagName('digits')[0].firstChild.data;
1192                 gxtEl.parent = JXG.GeonextReader.changeOriginIds(board,gxtEl.parent);
1193                 c = new JXG.Text(board, gxtEl.mpStr, gxtEl.parent, [gxtEl.x, gxtEl.y], gxtEl.id, gxtEl.name, gxtEl.autodigits, false,       board.options.text.defaultDisplay);
1194                 c.setProperty('labelColor:'+gxtEl.colorLabel, 'visible:'+gxtEl.visible);
1195                 /*if(gxtEl.visible == "false") {
1196                     c.hideElement();
1197                 } */
1198                 break;
1199             case 'parametercurve':
1200                 gxtEl = JXG.GeonextReader.colorProperties(gxtEl, Data);
1201                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
1202                 gxtEl.functionx = Data.getElementsByTagName('functionx')[0].firstChild.data;
1203                 gxtEl.functiony = Data.getElementsByTagName('functiony')[0].firstChild.data;
1204                 gxtEl.min = Data.getElementsByTagName('min')[0].firstChild.data;
1205                 gxtEl.max = Data.getElementsByTagName('max')[0].firstChild.data;
1206                 c = new JXG.Curve(board, ['t',gxtEl.functionx,gxtEl.functiony,gxtEl.min,gxtEl.max], gxtEl.id, gxtEl.name);
1207                 c.setProperty('strokeColor:'+gxtEl.colorStroke,'strokeWidth:'+gxtEl.strokewidth,'fillColor:none',
1208                               'highlightStrokeColor:'+gxtEl.highlightStrokeColor);
1209                 JXG.GeonextReader.printDebugMessage('debug',gxtEl,Data.nodeName,'OK');
1210                 break;
1211             case 'tracecurve':
1212                 gxtEl.tracepoint = Data.getElementsByTagName('tracepoint')[0].firstChild.data;
1213                 gxtEl.traceslider = Data.getElementsByTagName('traceslider')[0].firstChild.data;
1214                 JXG.GeonextReader.printDebugMessage('debug',gxtEl,Data.nodeName,'<b>ERR</b>');
1215                 break;
1216             case 'group':
1217                 gxtEl = JXG.GeonextReader.boardProperties(gxtEl, Data);
1218                 gxtEl = JXG.GeonextReader.colorProperties(gxtEl, Data);
1219                 gxtEl = JXG.GeonextReader.firstLevelProperties(gxtEl, Data);
1220                 gxtEl.members = [];
1221                 for(i=0; i<Data.getElementsByTagName('data')[0].getElementsByTagName('member').length; i++) {
1222                     gxtEl.members[i] = Data.getElementsByTagName('data')[0].getElementsByTagName('member')[i].firstChild.data;
1223                     gxtEl.members[i] = JXG.GeonextReader.changeOriginIds(board,gxtEl.members[i]);
1224                 }
1225                 c = new JXG.Group(board, gxtEl.id, gxtEl.name, gxtEl.members);
1226                 JXG.GeonextReader.printDebugMessage('debug',gxtEl,Data.nodeName,'OK');
1227                 break;
1228             default:
1229                 //if (Data.nodeName!="#text") {
1230                     //$('debug').innerHTML += "* <b>Err:</b> " + Data.nodeName + " not yet implemented <br>\n";
1231                 //}
1232         }
1233         delete(gxtEl);
1234     })(s);
1235     board.addConditions(boardTmp.conditions);
1236 
1237 };
1238 
1239 this.decodeString = function(str) {
1240     var unz;
1241     if (str.indexOf("<GEONEXT>")<0){
1242         unz = (new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(str))).unzip(); // war Gunzip ME
1243         if (unz=="")
1244             return str;
1245         else
1246             return unz;
1247     } else {
1248         return str;
1249     }
1250 };
1251 
1252 this.prepareString = function(fileStr){
1253     try {
1254         if (fileStr.indexOf('GEONEXT')<0) {
1255             fileStr = (JXG.GeonextReader.decodeString(fileStr))[0][0];  // Base64 decoding
1256         }
1257         // Hacks to enable not well formed XML. Will be redone in Algebra.geonext2JS and Board.addConditions
1258         fileStr = JXG.GeonextReader.fixXML(fileStr);
1259     } catch(e) {
1260         fileStr = '';
1261     }
1262     return fileStr;
1263 };
1264 
1265 this.fixXML = function(str) {
1266    var arr = ["active", "angle", "animate", "animated", "arc", "area", "arrow", "author", "autodigits", "axis", "back", "background", "board", "border", "bottom", "buttonsize", "cas", "circle", "color", "comment", "composition", "condition", "conditions", "content", "continuous", "control", "coord", "coordinates", "cross", "cs", "dash", "data", "description", "digits", "direction", "draft", "editable", "elements", "event", "file", "fill", "first", "firstarrow", "fix", "fontsize", "free", "full", "function", "functionx", "functiony", "GEONEXT", "graph", "grid", "group", "height", "id", "image", "info", "information", "input", "intersection", "item", "jsf", "label", "last", "lastarrow", "left", "lefttoolbar", "lighting", "line", "loop", "max", "maximized", "member", "middle", "midpoint", "min", "modifier", "modus", "mp", "mpx", "multi", "name", "onpolygon", "order", "origin", "output", "overline", "parametercurve", "parent", "point", "pointsnap", "polygon", "position", "radius", "radiusnum", "radiusvalue", "right", "section", "selectedlefttoolbar", "showconstruction", "showcoord", "showinfo", "showunit", "showx", "showy", "size", "slider", "snap", "speed", "src", "start", "stop", "straight", "stroke", "strokewidth", "style", "term", "text", "top", "trace", "tracecurve", "type", "unit", "value", "VERSION", "vertex", "viewport", "visible", "width", "wot", "x", "xooy", "xval", "y", "yval", "zoom"],
1267         list = arr.join('|'),
1268         regex = '\<(/?('+list+'))\>',
1269         expr = new RegExp(regex,'g');
1270 
1271     // First, we convert all < to < and > to >
1272     str = JXG.escapeHTML(str);
1273     // Second, we convert all GEONExT tags of the form <tag> back to <tag>
1274     str = str.replace(expr,'<$1>');
1275 
1276     str = str.replace(/(<content>.*)<arc>(.*<\/content>)/g,'$1<arc>$2');
1277     str = str.replace(/(<mp>.*)<arc>(.*<\/mpx>)/g,'$1<arc>$2');
1278     str = str.replace(/(<mpx>.*)<arc>(.*<\/mpx>)/g,'$1<arc>$2');
1279     return str;
1280 };
1281 
1282 }; // end: GeonextReader()
1283