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.CinderellaReader = new function() {
 26     this.parseData = function(board) {
 27         var dataLines, i, j, k, pCoords, defName, objName, defPoints, segment, 
 28             defRadius, circle, erg, poly, point, objName2, erg2, lines, point2, oX, oY, scale;
 29         dataLines = this.data.split('\n');
 30         for(i=0; i<dataLines.length; i++) {
 31             if(dataLines[i].search(/FreePoint.+/) != -1) { // freier Punkt
 32                 pCoords = dataLines[i].slice(dataLines[i].search(/FreePoint.+/)+11);
 33                 pCoords = pCoords.split(',');
 34                 for(j=0; j<pCoords.length; j++) {
 35                     pCoords[j] = pCoords[j].slice(0,pCoords[j].search(/\+i\*/));
 36                 }
 37                 objName = dataLines[i].match(/"[A-Za-z]*"/);
 38                 objName = objName[0].slice(1, objName[0].length-1);
 39                 erg = this.readPointProperties(dataLines,i);
 40                 i = erg[1];
 41                 board.create('point',[pCoords[0]/pCoords[2],-1*pCoords[1]/pCoords[2]],
 42                                     {name:objName, size:erg[0][1], fillColor:erg[0][0], strokeColor:erg[2], labelColor:erg[3]});
 43                 
 44             }
 45             else if(dataLines[i].search(/Join\(.+/) != -1 || dataLines[i].search(/Segment\(.+/) != -1) { // Gerade oder Strecke
 46                 if(dataLines[i].search(/Join\(.+/) != -1) {
 47                     defPoints = dataLines[i].slice(dataLines[i].search(/Join.+/)+5);
 48                     segment = false;
 49                 }
 50                 else {
 51                     defPoints = dataLines[i].slice(dataLines[i].search(/Segment.+/)+8);
 52                     segment = true;
 53                 }
 54                 defPoints = defPoints.split(',');
 55                 defName = [];
 56                 for(j=0; j<defPoints.length; j++) {
 57                     defName[j] = defPoints[j].match(/"[A-Za-z]*"/)[0];
 58                     defName[j] = defName[j].slice(1,defName[j].length-1);
 59                 }
 60                 objName = dataLines[i].match(/"[A-Za-z]*"/);
 61                 objName = objName[0].slice(1, objName[0].length-1);
 62                 erg = this.readLineProperties(dataLines,i);
 63                 i = erg[2];
 64                 board.create('line',[JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1])],
 65                                     {straightFirst:!segment, straightLast:!segment, name:objName, withLabel:true, 
 66                                      strokeColor:erg[0][0], strokeWidth:erg[0][2], dash:erg[1]});
 67             }
 68             else if(dataLines[i].search(/CircleMP.+/) != -1) { // Kreis, durch zwei Punkte definiert
 69                 defPoints = dataLines[i].slice(dataLines[i].search(/CircleMP.+/)+9);
 70                 defPoints = defPoints.split(',');
 71                 defName = [];
 72                 for(j=0; j<defPoints.length; j++) {
 73                     defName[j] = defPoints[j].match(/"[A-Za-z]*"/)[0];
 74                     defName[j] = defName[j].slice(1,defName[j].length-1);
 75                 }
 76                 objName = dataLines[i].match(/"[A-Za-z0-9]*"/);
 77                 objName = objName[0].slice(1, objName[0].length-1); 
 78                 erg = this.readCircleProperties(dataLines,i);
 79                 i = erg[3];
 80                 board.create('circle',[JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1])],
 81                                     {name:objName, strokeColor:erg[0][0], fillColor:erg[1], fillOpacity:erg[2],
 82                                      strokeWidth:erg[0][2]});
 83             }
 84             else if(dataLines[i].search(/CircleByFixedRadius.+/) != -1 || dataLines[i].search(/CircleByRadius.+/) != -1) { // Kreis, mit Radius
 85                 if(dataLines[i].search(/CircleByFixedRadius.+/) != -1) {
 86                     defPoints = dataLines[i].slice(dataLines[i].search(/CircleByFixedRadius.+/)+20);
 87                 }
 88                 else {
 89                     defPoints = dataLines[i].slice(dataLines[i].search(/CircleByRadius.+/)+15);
 90                 }
 91                 defPoints = defPoints.split(',');
 92                 defName = defPoints[0].match(/"[A-Za-z0-9]*"/)[0];
 93                 defName = defName.slice(1,defName.length-1);
 94                 objName = dataLines[i].match(/"[A-Za-z0-9]*"/);
 95                 objName = objName[0].slice(1, objName[0].length-1);
 96                 defRadius = defPoints[1].slice(0,defPoints[1].search(/\+i\*/));
 97                 erg = this.readCircleProperties(dataLines,i);
 98                 i = erg[3];
 99                 board.create('circle',[JXG.getReference(board,defName),Math.sqrt(1*defRadius)],
100                                     {name:objName, strokeColor:erg[0][0], fillColor:erg[1], fillOpacity:erg[2],
101                                      strokeWidth:erg[0][2]});
102             }
103             else if(dataLines[i].search(/PointOnCircle.+/) != -1) { // Gleiter auf Kreis
104                 defPoints = dataLines[i].split(':=');
105                 objName = defPoints[0].match(/"[A-Za-z]*"/)[0];
106                 objName = objName.slice(1, objName.length-1);
107                 defName = defPoints[1].match(/"[A-Za-z0-9]*"/)[0];
108                 defName = defName.slice(1,defName.length-1);  
109                 defPoints = defPoints[1].match(/\[.*\]/)[0];
110                 defPoints = defPoints.split(',');
111                 for(k=0; k<defPoints.length; k++) {
112                     defPoints[k] = defPoints[k].split('+i*');
113                 }
114                 defPoints[0] = 1*(defPoints[0][0].slice(1));
115                 defPoints[1] = 1*defPoints[1][0];
116                 if(dataLines[i][1] == 'n') { // umgedreht!
117                     defPoints[0] = -1*defPoints[0];
118                     defPoints[1] = -1*defPoints[1];
119                 }
120                 erg = this.readPointProperties(dataLines,i);
121                 i = erg[1];
122                 circle = JXG.getReference(board,defName);
123                 board.create('glider',
124                         [circle.center.coords.usrCoords[1]+defPoints[0],circle.center.coords.usrCoords[2]-defPoints[1],circle],
125                                 {name:objName, size:erg[0][1], fillColor:erg[0][0], strokeColor:erg[2], labelColor:erg[3]});
126             }
127             else if(dataLines[i].search(/PointOnLine.+/) != -1) { // Gleiter auf Geade
128                 defPoints = dataLines[i].split(':=');
129                 objName = defPoints[0].match(/"[A-Za-z]*"/)[0];
130                 objName = objName.slice(1, objName.length-1);
131                 defName = defPoints[1].match(/"[A-Za-z0-9]*"/)[0];
132                 defName = defName.slice(1,defName.length-1);
133                 pCoords = defPoints[1].match(/\[.*\]/)[0];
134                 pCoords = pCoords.split(',');
135                 pCoords[0] = 1*(pCoords[0].slice(1,pCoords[0].search(/\+i\*/))); // Klammer mit wegschneiden
136                 for(j=1; j<pCoords.length; j++) {
137                     pCoords[j] = 1*(pCoords[j].slice(0,pCoords[j].search(/\+i\*/)));
138                 }            
139                 erg = this.readPointProperties(dataLines,i);
140                 i = erg[1];
141                 board.create('glider',
142                         [pCoords[0]/pCoords[2],-1*pCoords[1]/pCoords[2],JXG.getReference(board,defName)],
143                         {name:objName, size:erg[0][1], fillColor:erg[0][0], strokeColor:erg[2], labelColor:erg[3]});  
144             }
145             else if(dataLines[i].search(/Mid\(.+/) != -1) { // Mittelpunkt
146                 defPoints = dataLines[i].slice(dataLines[i].search(/Mid.+/)+4);
147                 defPoints = defPoints.split(',');
148                 defName = [];
149                 for(j=0; j<defPoints.length; j++) {
150                     defName[j] = defPoints[j].match(/"[A-Za-z]*"/)[0];
151                     defName[j] = defName[j].slice(1,defName[j].length-1);
152                 }
153                 objName = dataLines[i].match(/"[A-Za-z0-9]*"/);
154                 objName = objName[0].slice(1, objName[0].length-1); 
155                 erg = this.readPointProperties(dataLines,i);
156                 i = erg[1];
157                 board.create('midpoint',
158                         [JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1])],
159                         {name:objName, size:erg[0][1], fillColor:erg[0][0], strokeColor:erg[2], labelColor:erg[3]});
160             }
161             else if(dataLines[i].search(/CircleBy3\(.+/) != -1) { // Umkreis
162                 defPoints = dataLines[i].slice(dataLines[i].search(/CircleBy3.+/)+10);
163                 defPoints = defPoints.split(',');
164                 defName = [];
165                 for(j=0; j<defPoints.length; j++) {
166                     defName[j] = defPoints[j].match(/"[A-Za-z]*"/)[0];
167                     defName[j] = defName[j].slice(1,defName[j].length-1);
168                 }
169                 objName = dataLines[i].match(/"[A-Za-z0-9]*"/);
170                 objName = objName[0].slice(1, objName[0].length-1);
171                 erg = this.readCircleProperties(dataLines,i);
172                 i = erg[3]; 
173                 circle = board.create('circumcircle',
174                         [JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1]),JXG.getReference(board,defName[2])],
175                         {name:objName, strokeColor:erg[0][0], fillColor:erg[1], fillOpacity:erg[2],
176                          strokeWidth:erg[0][2],
177                          point:{name:'', visible:false}
178                         });
179             }
180             else if(dataLines[i].search(/Parallel\(.+/) != -1) { // Parallele
181                 defPoints = dataLines[i].slice(dataLines[i].search(/Parallel.+/)+9);
182                 defPoints = defPoints.split(',');
183                 defName = [];
184                 for(j=0; j<defPoints.length; j++) {
185                     defName[j] = defPoints[j].match(/"[A-Za-z]*"/)[0];
186                     defName[j] = defName[j].slice(1,defName[j].length-1);
187                 }
188                 objName = dataLines[i].match(/"[A-Za-z0-9]*"/);
189                 objName = objName[0].slice(1, objName[0].length-1);
190                 erg = this.readLineProperties(dataLines,i);
191                 i = erg[2];
192                 board.create('parallel',
193                         [JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1])],
194                         {name:objName, withLabel:true, strokeColor:erg[0][0], strokeWidth:erg[0][2], dash:erg[1]});
195             }
196             else if(dataLines[i].search(/Orthogonal\(.+/) != -1) { // Normale
197                 defPoints = dataLines[i].slice(dataLines[i].search(/Parallel.+/)+11);
198                 defPoints = defPoints.split(',');
199                 defName = [];
200                 for(j=0; j<defPoints.length; j++) {
201                     defName[j] = defPoints[j].match(/"[A-Za-z]*"/)[0];
202                     defName[j] = defName[j].slice(1,defName[j].length-1);
203                 }
204                 objName = dataLines[i].match(/"[A-Za-z0-9]*"/);
205                 objName = objName[0].slice(1, objName[0].length-1);
206                 erg = this.readLineProperties(dataLines,i);
207                 i = erg[2];                
208                 board.create('normal',
209                         [JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1])],
210                         {name:objName, withLabel:true, strokeColor:erg[0][0], strokeWidth:erg[0][2], dash:erg[1]});                
211             }
212             else if(dataLines[i].search(/ConicBy5\(.+/) != -1) { // Kegelschnitt durch 5 Punkte
213                 defPoints = dataLines[i].slice(dataLines[i].search(/ConicBy5.+/)+9);
214                 defPoints = defPoints.split(',');
215                 defName = [];
216                 for(j=0; j<defPoints.length; j++) {
217                     defName[j] = defPoints[j].match(/"[A-Za-z]*"/)[0];
218                     defName[j] = defName[j].slice(1,defName[j].length-1);
219                 }
220                 objName = dataLines[i].match(/"[A-Za-z0-9]*"/);
221                 objName = objName[0].slice(1, objName[0].length-1); 
222                 erg = this.readCircleProperties(dataLines,i);
223                 i = erg[3];
224                 board.create('conic',[JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1]),
225                                              JXG.getReference(board,defName[2]),JXG.getReference(board,defName[3]),
226                                              JXG.getReference(board,defName[4])],
227                                     {name: objName, strokeColor:erg[0][0], fillColor:erg[1], fillOpacity:erg[2],
228                                      strokeWidth:erg[0][2]});
229             }
230             else if(dataLines[i].search(/ConicFoci\(.+/) != -1 || dataLines[i].search(/ConicFociH\(.+/) != -1) { // Ellipse mit Brennpunkten und Punkt auf Ellipse resp. eine solche Hyperbel (ConicFociH)
231                 defPoints = dataLines[i].split(':=');
232                 objName = defPoints[0].match(/"[A-Za-z0-9]*"/)[0];
233                 objName = objName.slice(1, objName.length-1);
234                 defName = defPoints[1].match(/"[A-Za-z0-9]*"/g);
235                 for(j=0; j<defName.length; j++) {
236                     defName[j] = defName[j].slice(1,defName[j].length-1);
237                 }
238                 erg = this.readCircleProperties(dataLines,i);
239                 if(dataLines[i].search(/ConicFociH\(.+/) != -1) {
240                     board.create('hyperbola',[JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1]),
241                                                 JXG.getReference(board,defName[2])],
242                                         {name: objName, strokeColor:erg[0][0], fillColor:erg[1], fillOpacity:erg[2],
243                                          strokeWidth:erg[0][2]});
244                 }
245                 else {
246                     board.create('ellipse',[JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1]),
247                                                 JXG.getReference(board,defName[2])],
248                                         {name: objName, strokeColor:erg[0][0], fillColor:erg[1], fillOpacity:erg[2],
249                                          strokeWidth:erg[0][2]});                
250                 }
251                 i = erg[3];
252             }
253             else if(dataLines[i].search(/ConicParabolaPL\(.+/) != -1) { // Parabel mit Brennpunkt und Leitlinie
254                 defPoints = dataLines[i].slice(dataLines[i].search(/ConicParabolaPL.+/)+16);
255                 defPoints = defPoints.split(',');
256                 defName = [];
257                 for(j=0; j<defPoints.length; j++) {
258                     defName[j] = defPoints[j].match(/"[A-Za-z]*"/)[0];
259                     defName[j] = defName[j].slice(1,defName[j].length-1);
260                 }
261                 objName = dataLines[i].match(/"[A-Za-z0-9]*"/);
262                 objName = objName[0].slice(1, objName[0].length-1);
263                 erg = this.readCircleProperties(dataLines,i);
264                 i = erg[3];                
265                 board.create('parabola',
266                         [JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1])],
267                                         {name: objName, strokeColor:erg[0][0], fillColor:erg[1], fillOpacity:erg[2],
268                                          strokeWidth:erg[0][2]});                 
269             }
270             else if(dataLines[i].search(/Poly\(.+/) != -1) { // Polygon
271                 defPoints = dataLines[i].slice(dataLines[i].search(/Poly.+/)+5);
272                 defPoints = defPoints.split(',');
273                 defName = [];
274                 for(j=0; j<defPoints.length; j++) {
275                     defName[j] = defPoints[j].match(/"[A-Za-z]*"/)[0];
276                     defName[j] = defName[j].slice(1,defName[j].length-1);
277                     defName[j] = JXG.getReference(board,defName[j]);
278                 }
279                 objName = dataLines[i].match(/"[A-Za-z0-9]*"/);
280                 objName = objName[0].slice(1, objName[0].length-1);
281                 erg = this.readCircleProperties(dataLines,i);
282                 i = erg[3];                  
283                 poly = board.create('polygon', defName,
284                                         {name: objName}); 
285                 poly.setProperty({fillColor:erg[1], fillOpacity:erg[2]});
286                 for(j=0; j<poly.borders.length; j++) {
287                     poly.borders[j].setProperty({strokeColor:erg[0][0],strokeWidth:erg[0][2]});
288                 }
289             } 
290             else if(dataLines[i].search(/Arc\(.+/) != -1) { // Polygon
291                 defPoints = dataLines[i].slice(dataLines[i].search(/Arc.+/)+4);
292                 defPoints = defPoints.split(',');
293                 defName = [];
294                 for(j=0; j<defPoints.length; j++) {
295                     defName[j] = defPoints[j].match(/"[A-Za-z]*"/)[0];
296                     defName[j] = defName[j].slice(1,defName[j].length-1);
297                 }
298                 objName = dataLines[i].match(/"[A-Za-z0-9]*"/);
299                 objName = objName[0].slice(1, objName[0].length-1);
300                 erg = this.readCircleProperties(dataLines,i);
301                 i = erg[3];                     
302                 poly = board.create('circumcirclearc', [JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1]),
303                                                    JXG.getReference(board,defName[2])],
304                                         {name: objName, strokeColor:erg[0][0], fillColor:erg[1], fillOpacity:erg[2],
305                                          strokeWidth:erg[0][2]});
306             } 
307             else if(dataLines[i].search(/Through\(.+/) != -1) { // durch einen Punkt definierte Gerade
308                 defPoints = dataLines[i].slice(dataLines[i].search(/Through.+/)+8);
309                 defName = defPoints.match(/"[A-Za-z]*"/)[0];
310                 defName = defName.slice(1,defName.length-1);
311                 pCoords = defPoints.match(/\[.*\]/)[0];
312                 pCoords = pCoords.split(',');
313                 pCoords[0] = 1*(pCoords[0].slice(1,pCoords[0].search(/\+i\*/))); // Klammer mit wegschneiden
314                 for(j=1; j<pCoords.length; j++) {
315                     pCoords[j] = 1*(pCoords[j].slice(0,pCoords[j].search(/\+i\*/)));
316                 } 
317                 objName = dataLines[i].match(/"[A-Za-z0-9]*"/);
318                 objName = objName[0].slice(1, objName[0].length-1);
319                 
320                 j = JXG.getReference(board,defName);
321                 point = board.create('point',[j.coords.usrCoords[1]+1*pCoords[0],j.coords.usrCoords[2]+1*pCoords[1]],{visible:false});
322                 erg = this.readLineProperties(dataLines,i);
323                 i = erg[2];
324                 board.create('line',[j,point],
325                                     {name:objName, withLabel:true, strokeColor:erg[0][0], strokeWidth:erg[0][2], dash:erg[1]});
326             }
327             else if(dataLines[i].search(/:=Compass\(.+/) != -1) { // mit Zirkel definierter Kreis
328                 defPoints = dataLines[i].slice(dataLines[i].search(/Compass.+/)+8);
329                 defPoints = defPoints.split(',');
330                 defName = [];
331                 for(j=0; j<defPoints.length; j++) {
332                     defName[j] = defPoints[j].match(/"[A-Za-z]*"/)[0];
333                     defName[j] = defName[j].slice(1,defName[j].length-1);
334                 }
335                 objName = dataLines[i].match(/"[A-Za-z0-9]*"/);
336                 objName = objName[0].slice(1, objName[0].length-1);
337                 erg = this.readCircleProperties(dataLines,i);
338                 i = erg[3];   
339                 defRadius = (function(el, b) {
340                 				return function() { 
341                                             return JXG.getReference(b,el[0]).Dist(JXG.getReference(b,el[1])); 
342                                        };
343                                 })(defName, board);                
344                 board.create('circle',
345                                     [JXG.getReference(board,defName[2]), defRadius],
346                                     {name:objName, strokeColor:erg[0][0], fillColor:erg[1], fillOpacity:erg[2],
347                                      strokeWidth:erg[0][2]});
348             }
349             else if(dataLines[i].search(/AngularBisector\(.+/) != -1) { // Winkelhalbierende
350                 defPoints = dataLines[i].split(":=");
351                 defPoints[0] = defPoints[0].split(',');
352                 if(defPoints[0][0] == '{null') {
353                     objName = '';
354                 }
355                 else {
356                     objName = defPoints[0][0].slice(2,defPoints[0][0].length-1); // { muss mit weg
357                 }
358                 if(defPoints[0][1] == 'null') {
359                     objName2 = '';
360                 }
361                 else {
362                     objName2 = defPoints[0][1].slice(1,defPoints[0][1].length-1);
363                 }
364                 defPoints[1] = defPoints[1].match(/"[A-Za-z0-9]*"/g);
365                 defName = [];
366                 defName[0] = defPoints[1][0].slice(1,defPoints[1][0].length-1);
367                 defName[1] = defPoints[1][1].slice(1,defPoints[1][1].length-1);
368                 erg = this.readLineProperties(dataLines,i);
369                 i = erg[2];
370                 if(!(objName == '' || objName2 == '')) {
371                     erg2 = this.readLineProperties(dataLines,i);
372                     i = erg[2];
373                 }
374                 lines = board.create('bisectorlines',[JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1])],
375                                            {line1: {name:objName2},
376                                             line2: {name:objName}, 
377                                             withLabel:true});
378                 if(objName == '') {
379                     lines.line2.setProperty({visible:false});
380                     lines.line1.setProperty({strokeColor:erg[0][0], strokeWidth:erg[0][2], dash:erg[1]});
381                 }
382                 else {
383                     if(objName2 == '') {
384                         lines.line1.setProperty({visible:false});
385                         lines.line2.setProperty({strokeColor:erg[0][0], strokeWidth:erg[0][2], dash:erg[1]});
386                     }
387                     else {
388                         lines.line1.setProperty({strokeColor:erg[0][0], strokeWidth:erg[0][2], dash:erg[1]});
389                         lines.line2.setProperty({strokeColor:erg2[0][0], strokeWidth:erg2[0][2], dash:erg2[1]});
390                     }
391                 }
392             }
393             else if(dataLines[i].search(/Meet\(.+/) != -1) { // Schnitt zweier Geraden
394                 defPoints = dataLines[i].slice(dataLines[i].search(/Meet.+/)+5);
395                 defPoints = defPoints.split(',');
396                 defName = [];
397                 for(j=0; j<defPoints.length; j++) {
398                     defName[j] = defPoints[j].match(/"[A-Za-z]*"/)[0];
399                     defName[j] = defName[j].slice(1,defName[j].length-1);
400                 }
401                 objName = dataLines[i].match(/"[A-Za-z0-9]*"/);
402                 objName = objName[0].slice(1, objName[0].length-1);
403                 erg = this.readPointProperties(dataLines,i);
404                 i = erg[1];                  
405                 board.create('intersection',
406                                     [JXG.getReference(board,defName[0]), JXG.getReference(board,defName[1]),0],
407                                     {name:objName, size:erg[0][1], fillColor:erg[0][0], strokeColor:erg[2], labelColor:erg[3]});
408             } 
409             else if(dataLines[i].search(/IntersectionConicLine\(.+/) != -1 || dataLines[i].search(/IntersectionCircleCircle\(.+/) != -1) { // Schnitt Kreis/Gerade oder Schnitt Kreis/Kreis
410                 if(dataLines[i].search(/IntersectionConicLine\(.+/) != -1) {
411                     k = 0;
412                     j = 1;
413                 }
414                 else {
415                     k = 1;
416                     j = 0;
417                 }
418                 defPoints = dataLines[i].split(":=");
419                 defPoints[0] = defPoints[0].split(',');
420                 if(defPoints[0][0] == '{null') {
421                     objName = '';
422                 }
423                 else {
424                     objName = defPoints[0][0].slice(2,defPoints[0][0].length-1); // { muss mit weg
425                 }
426                 if(defPoints[0][1] == 'null') {
427                     objName2 = '';
428                 }
429                 else {
430                     objName2 = defPoints[0][1].slice(1,defPoints[0][1].length-1);
431                 }
432                 defPoints[1] = defPoints[1].match(/"[A-Za-z0-9]*"/g);
433                 defName = [];
434                 defName[0] = defPoints[1][0].slice(1,defPoints[1][0].length-1);
435                 defName[1] = defPoints[1][1].slice(1,defPoints[1][1].length-1);
436                 erg = this.readPointProperties(dataLines,i);
437                 i = erg[1];
438                 if(!(objName == '' || objName2 == '')) {
439                     erg2 = this.readPointProperties(dataLines,i);
440                     i = erg[1];
441                 }
442                 if(objName2 != '') {
443                     point = board.create('intersection',
444                                                 [JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1]),j],
445                                                 {name:objName2, size:erg[0][1], fillColor:erg[0][0], strokeColor:erg[2], labelColor:erg[3]});
446                     if(objName != '') {
447                         point2 = board.create('otherintersection', 
448                                               [JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1]), point], 
449                                               {name:objName, size:erg2[0][1], fillColor:erg2[0][0], strokeColor:erg2[2], labelColor:erg2[3]});
450                     }
451                 }
452                 else {
453                     point = board.create('intersection',
454                                                 [JXG.getReference(board,defName[0]),JXG.getReference(board,defName[1]),k],
455                                                 {name:objName, size:erg[0][1], fillColor:erg[0][0], strokeColor:erg[2], labelColor:erg[3]});
456                 }
457             }
458             else if(dataLines[i].search(/setOriginX\(([0-9.]*)\)/) != -1) {
459                 //alert("X= "+RegExp.$1);
460                 oX = RegExp.$1;
461             }              
462             else if(dataLines[i].search(/setOriginY\(([0-9.]*)\)/) != -1) {
463                 //alert(RegExp.$1);
464                 oY = RegExp.$1;
465                 //alert("_"+oY+"_");
466             }
467             else if(dataLines[i].search(/setScale\(([0-9.]*)\)/) != -1) {
468                 //alert(RegExp.$1);
469                 scale = 1*RegExp.$1/25.0;
470                 //alert(scale);
471             }
472                //setScale(25.0);
473           
474         }
475         
476         board.zoomX *= scale/2.4;
477         board.zoomY *= scale/2.4;
478         oX = board.origin.scrCoords[1]*board.options.zoom.factorX;
479         oY = board.origin.scrCoords[2]*board.options.zoom.factorY;
480         board.origin = new JXG.Coords(JXG.COORDS_BY_SCREEN, [oX-150, oY+50],board);
481         board.applyZoom();
482         return board;
483     };
484     
485     this.calculateColor = function(colNr) {
486         colNr = parseInt(colNr);
487         switch(colNr) {
488             case 0: return 'white';
489             case 1: return 'black';
490             case 2: return 'red';
491             case 3: return 'blue';
492             case 4: return 'green';
493             case 5: return 'yellow';
494             case 6: return '#ffafaf';
495             case 7: return 'cyan';
496             case 8: return '#ffc800';
497             case 9: return '#199e4e';
498             case 10: return '#b75500';
499             case 11: return '#7700b7';
500             case 12: return '#ff7f00';
501             case 13: return '#03a7bc';
502             case 14: return '#c10000';
503             case 15: return '#808080';
504             case 16: return '#ff4a4a';
505             case 17: return '#faff9e';
506             case 18: return '#b6ffaa';
507             case 19: return '#82f2ff';
508             case 20: return '#d4a3ff';
509             case 21: return '#ffbd77';            
510         }
511     };
512     
513     this.readPointProperties = function(dataLines,i) {
514         var objAppearance,border, labelcolor;
515         do {
516             i = i+1;
517         } while(dataLines[i].search(/setAppearance/) == -1);
518         objAppearance = (dataLines[i].match(/\([A-Za-z,0-9\.]*\)/))[0];
519         objAppearance = objAppearance.slice(1, objAppearance.length-1).split(',');
520         objAppearance[0] = this.calculateColor(objAppearance[0]);
521         do {
522             i = i+1;
523         } while(dataLines[i].search(/pointborder/) == -1);
524         if(dataLines[i].search(/false/) != -1) {
525             border = 'none';
526             labelcolor = objAppearance[0];
527         }
528         else {
529             border = 'black';
530             labelcolor = 'black';
531         } 
532         return [objAppearance,i,border,labelcolor];       
533     };
534     
535     this.readCircleProperties = function(dataLines,i) {
536         var objAppearance,filling, fillop;
537         do {
538             i = i+1;
539         } while(dataLines[i].search(/setAppearance/) == -1);
540         objAppearance = (dataLines[i].match(/\([A-Za-z,0-9\.]*\)/))[0];
541         objAppearance = objAppearance.slice(1, objAppearance.length-1).split(',');
542         objAppearance[0] = this.calculateColor(objAppearance[0]); 
543         do {
544             i = i+1;
545         } while(dataLines[i].search(/colorfill/) == -1);          
546         filling = dataLines[i].match(/"[0-9]*"/)[0];
547         filling = filling.slice(1,filling.length-1);
548         filling = this.calculateColor(filling);
549         do {
550             i = i+1;
551         } while(dataLines[i].search(/visibilityfill|fillalpha/) == -1); 
552         fillop = dataLines[i].match(/"[0-9\.]*"/)[0];
553         fillop = fillop.slice(1,fillop.length-1);
554         if(dataLines[i].match(/visibilityfill/)) {
555             fillop = 1*fillop/10;  
556         }
557         else {
558             fillop = 1*fillop;
559         }
560         return [objAppearance,filling, fillop,i];
561     };
562     
563     this.readLineProperties = function(dataLines,i) {
564         var objAppearance,dashing;
565         do {
566             i = i+1;
567         } while(dataLines[i].search(/setAppearance/) == -1);
568         objAppearance = (dataLines[i].match(/\([A-Za-z,0-9\.]*\)/))[0];
569         objAppearance = objAppearance.slice(1, objAppearance.length-1).split(',');
570         objAppearance[0] = this.calculateColor(objAppearance[0]);
571         do {
572             i = i+1;
573         } while(dataLines[i].search(/linedashing/) == -1);
574         if(dataLines[i].search(/false/) != -1) {
575             dashing = 0;
576         }
577         else {
578             dashing = 3;
579         }
580         return [objAppearance,dashing,i];
581     };
582     
583 	this.prepareString = function(fileStr) {
584         var i, bA = [], len;
585   		if (fileStr.indexOf('<') != 0) {
586             len = fileStr.length;
587 		    for (i=0;i<len;i++)
588 		    	bA[i]=JXG.Util.asciiCharCodeAt(fileStr,i);
589 		    // Unzip
590 		    fileStr = (new JXG.Util.Unzip(bA)).unzip()[0][0];
591 		}
592 		//fileStr = JXG.Util.utf8Decode(fileStr);
593 		//fileStr = JXG.GeogebraReader.utf8replace(fileStr);
594 		return fileStr;
595 	};
596 	
597 	this.readCinderella = function(fileStr, board){
598 		this.data = this.prepareString(fileStr);
599         board.suspendUpdate();
600 		this.parseData(board);
601         board.unsuspendUpdate();
602 	};
603 
604 };
605