1 /*
  2     Copyright 2008-2012
  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 /**
 26  * Options Namespace
 27  * @description These are the default options of the board and of all geometry elements.
 28  */
 29 JXG.Options = {
 30     /* Options that are used directly within the board class */
 31     showCopyright : true,
 32     showNavigation : true,
 33     takeSizeFromFile : false, // If true, the construction - when read from a file or string - the size of the div can be changed.
 34     renderer: 'svg',
 35     takeFirst : false, // if true the first element with hasPoint==true is taken.
 36     pan: true,
 37 
 38     /* zoom options */
 39     zoom : {
 40         factorX : 1.25,
 41         factorY : 1.25,
 42         wheel: false
 43     },
 44 
 45     jc : {
 46         enabled: true,
 47         compile: true
 48     },
 49 
 50     /* navbar options */
 51     navbar: {
 52         strokeColor: '#aaaaaa',
 53         fillColor: '#f5f5f5',
 54         padding: '2px',
 55         position: 'absolute',
 56         fontSize: '10px',
 57         cursor: 'pointer',
 58         zIndex: '100',
 59         right: '5px',
 60         bottom: '5px'
 61     },
 62 
 63     /**
 64      * Generic options 
 65      */
 66     
 67     /* geometry element options */
 68     elements : {
 69         // the following tag is a meta tag: http://code.google.com/p/jsdoc-toolkit/wiki/MetaTags
 70 
 71         /**#@+
 72          * @visprop
 73          */
 74 
 75         /**
 76          * The stroke color of the given geometry element.
 77          * @type String
 78          * @name JXG.GeometryElement#strokeColor
 79          * @see JXG.GeometryElement#highlightStrokeColor
 80          * @see JXG.GeometryElement#strokeWidth
 81          * @see JXG.GeometryElement#strokeOpacity
 82          * @see JXG.GeometryElement#highlightStrokeOpacity
 83          * @default {@link JXG.Options.elements.color#strokeColor}
 84          */
 85         strokeColor: '#0000ff',
 86 
 87         /**
 88          * The stroke color of the given geometry element when the user moves the mouse over it.
 89          * @type String
 90          * @name JXG.GeometryElement#highlightStrokeColor
 91          * @see JXG.GeometryElement#strokeColor
 92          * @see JXG.GeometryElement#strokeWidth
 93          * @see JXG.GeometryElement#strokeOpacity
 94          * @see JXG.GeometryElement#highlightStrokeOpacity
 95          * @default {@link JXG.Options.elements.color#highlightStrokeColor}
 96          */
 97         highlightStrokeColor: '#C3D9FF',
 98 
 99         /**
100          * The fill color of this geometry element.
101          * @type String
102          * @name JXG.GeometryElement#fillColor
103          * @see JXG.GeometryElement#highlightFillColor
104          * @see JXG.GeometryElement#fillOpacity
105          * @see JXG.GeometryElement#highlightFillOpacity
106          * @default {@link JXG.Options.elements.color#fillColor}
107          */
108         fillColor: 'red',
109 
110         /**
111          * The fill color of the given geometry element when the mouse is pointed over it.
112          * @type String
113          * @name JXG.GeometryElement#highlightFillColor
114          * @see JXG.GeometryElement#fillColor
115          * @see JXG.GeometryElement#fillOpacity
116          * @see JXG.GeometryElement#highlightFillOpacity
117          * @default {@link JXG.Options.elements.color#highlightFillColor}
118          */
119         highlightFillColor: 'none',
120 
121         /**
122          * Opacity for element's stroke color.
123          * @type number
124          * @name JXG.GeometryElement#strokeOpacity
125          * @see JXG.GeometryElement#strokeColor
126          * @see JXG.GeometryElement#highlightStrokeColor
127          * @see JXG.GeometryElement#strokeWidth
128          * @see JXG.GeometryElement#highlightStrokeOpacity
129          * @default {@link JXG.Options.elements#strokeOpacity}
130          */
131         strokeOpacity: 1,
132 
133         /**
134          * Opacity for stroke color when the object is highlighted.
135          * @type number
136          * @name JXG.GeometryElement#highlightStrokeOpacity
137          * @see JXG.GeometryElement#strokeColor
138          * @see JXG.GeometryElement#highlightStrokeColor
139          * @see JXG.GeometryElement#strokeWidth
140          * @see JXG.GeometryElement#strokeOpacity
141          * @default {@link JXG.Options.elements#highlightStrokeOpacity}
142          */
143         highlightStrokeOpacity: 1,
144 
145         /**
146          * Opacity for fill color.
147          * @type number
148          * @name JXG.GeometryElement#fillOpacity
149          * @see JXG.GeometryElement#fillColor
150          * @see JXG.GeometryElement#highlightFillColor
151          * @see JXG.GeometryElement#highlightFillOpacity
152          * @default {@link JXG.Options.elements.color#fillOpacity}
153          */
154         fillOpacity: 1,
155 
156         /**
157          * Opacity for fill color when the object is highlighted.
158          * @type number
159          * @name JXG.GeometryElement#highlightFillOpacity
160          * @see JXG.GeometryElement#fillColor
161          * @see JXG.GeometryElement#highlightFillColor
162          * @see JXG.GeometryElement#fillOpacity
163          * @default {@link JXG.Options.elements.color#highlightFillOpacity}
164          */
165         highlightFillOpacity: 1,
166 
167         /**
168          * Width of the element's stroke.
169          * @type number
170          * @name JXG.GeometryElement#strokeWidth
171          * @see JXG.GeometryElement#strokeColor
172          * @see JXG.GeometryElement#highlightStrokeColor
173          * @see JXG.GeometryElement#strokeOpacity
174          * @see JXG.GeometryElement#highlightStrokeOpacity
175          * @default {@link JXG.Options.elements#strokeWidth}
176          */
177         strokeWidth: 2,
178 
179         /**
180          * Width of the element's stroke when the mouse is pointed over it.
181          * @type number
182          * @name JXG.GeometryElement#highlightStrokeWidth
183          * @see JXG.GeometryElement#strokeColor
184          * @see JXG.GeometryElement#highlightStrokeColor
185          * @see JXG.GeometryElement#strokeOpacity
186          * @see JXG.GeometryElement#highlightStrokeOpacity
187          * @see JXG.GeometryElement#highlightFillColor
188          * @default {@link JXG.Options.elements#strokeWidth}
189          */
190         highlightStrokeWidth: 2,
191 
192 
193         /**
194          * If true the element is fixed and can not be dragged around. The element
195          * will be repositioned on zoom and moveOrigin events.
196          * @type Boolean
197          * @default false
198          * @name JXG.GeometryElement#fixed
199          */
200         fixed: false,
201 
202         /**
203          * If true the element is fixed and can not be dragged around. The element
204          * will even stay at its position on zoom and moveOrigin events.
205          * Only free elements like points, texts, curves can be frozen.
206          * @type Boolean
207          * @default false
208          * @name JXG.GeometryElement#frozen
209          */
210         frozen: false,
211 
212         /**
213          * If true a label will display the element's name.
214          * @type Boolean
215          * @default false
216          * @name JXG.GeometryElement#withLabel
217          */
218         withLabel: false,
219 
220         /**
221          * If false the element won't be visible on the board, otherwise it is shown.
222          * @type boolean
223          * @name JXG.GeometryElement#visible
224          * @see JXG.GeometryElement#hideElement
225          * @see JXG.GeometryElement#showElement
226          * @default true
227          */
228         visible: true,
229 
230         /**
231          * Display layer which will contain the element.
232          * @see JXG.Options#layer
233          * @default See {@link JXG.Options#layer}
234          */
235         layer: 0,
236 
237 
238         /**
239          * Determines the elements border-style.
240          * Possible values are:
241          * <ul><li>0 for a solid line</li>
242          * <li>1 for a dotted line</li>
243          * <li>2 for a line with small dashes</li>
244 
245 
246          * <li>3 for a line with medium dashes</li>
247          * <li>4 for a line with big dashes</li>
248          * <li>5 for a line with alternating medium and big dashes and large gaps</li>
249          * <li>6 for a line with alternating medium and big dashes and small gaps</li></ul>
250          * @type Number
251          * @name JXG.GeometryElement#dash
252          * @default 0
253          */
254         dash: 0,
255 
256         /**
257          * If true the element will get a shadow.
258          * @type boolean
259          * @name JXG.GeometryElement#shadow
260          * @default false
261          */
262         shadow: false,
263 
264         /**
265          * If true the element will be traced, i.e. on every movement the element will be copied
266          * to the background. Use {@link JXG.GeometryElement#clearTrace} to delete the trace elements.
267          * @see JXG.GeometryElement#clearTrace
268          * @see JXG.GeometryElement#traces
269          * @see JXG.GeometryElement#numTraces
270          * @type Boolean
271          * @default false
272          * @name JXG.GeometryElement#trace
273          */
274         trace: false,
275 
276         /**
277          * Extra visual properties for traces of an element
278          * @type Object
279          * @see JXG.GeometryElement#trace
280          * @name JXG.GeometryElement#traceAttributes
281          */
282         traceAttributes: {},
283         
284         /**
285          * 
286          * @type Boolean
287          * @default true
288          * @name JXG.GeometryElement#highlight
289          */
290         highlight: true,
291         
292         /**
293          * If this is set to true, the element is updated in every update
294          * call of the board. If set to false, the element is updated only after
295          * zoom events or more generally, when the bounding box has been changed.
296          * Examples for the latter behaviour should be axes.
297          * @type Boolean
298          * @default true
299          * @see JXG.GeometryElement#needsRegularUpdate
300          * @name JXG.GeometryElement#needsRegularUpdate
301          */
302         needsRegularUpdate: true,
303 
304         /*draft options */
305         draft : {
306             /**
307              * If true the element will be drawn in grey scale colors to visualize that it's only a draft.
308              * @type boolean
309              * @name JXG.GeometryElement#draft
310              * @default {@link JXG.Options.elements.draft#draft}
311              */
312             draft : false,
313             strokeColor : '#565656',
314             fillColor : '#565656',
315             strokeOpacity : 0.8,
316             fillOpacity : 0.8,
317             strokeWidth : 1
318         }
319         // close the meta tag
320         /**#@-*/
321     },
322 
323     ticks : {
324         /**#@+
325          * @visprop
326          */
327 
328         /**
329          * Draw labels yes/no
330          * @type Boolean
331          * @name JXG.Ticks#drawLabels
332          * @default false
333          */
334         drawLabels: false,
335         
336         /**
337          * Draw the zero tick, that lies at line.point1?
338          * @type Boolean
339          * @name JXG.Ticks#drawZero
340          * @default false
341          */
342         drawZero: false,
343 
344         /**
345          * If the distance between two ticks is too big we could insert new ticks. If insertTicks
346          * is <tt>true</tt>, we'll do so, otherwise we leave the distance as is.
347          * This option is ignored if equidistant is false.
348          * @type Boolean
349          * @name JXG.Ticks#insertTicks
350          * @see JXG.Ticks#equidistant
351          * @see JXG.Ticks#maxTicksDistance
352          * @default false
353          */
354         insertTicks: false,
355         minTicksDistance: 50,
356 
357         /**
358          * Total height of a minor tick. If negative the full height of the board is taken.
359          * @type Number
360          * @name JXG.Ticks#minorHeight
361          */
362         minorHeight: 4,
363 
364         /**
365          * Total height of a major tick. If negative the full height of the board is taken.
366          * @type Number
367          * @name JXG.Ticks#majorHeight
368          */
369         majorHeight: 10,
370 
371         /**
372          * The number of minor ticks between two major ticks.
373          * @type Number
374          * @name JXG.Ticks#minorTicks
375          */
376         minorTicks: 4,
377 
378         /**
379          * The default distance between two ticks. Please be aware that this value does not have
380          * to be used if {@link JXG.Ticks#insertTicks} is set to true.
381          * @type Boolean
382          * @name JXG.Ticks#ticksDistance
383          * @see JXG.Ticks#equidistant
384          * @see JXG.Ticks#insertTicks
385          * @default 1
386          */
387         ticksDistance: 1,
388         strokeOpacity: 1,
389         strokeWidth: 1,
390         strokeColor: 'black',
391         highlightStrokeColor: '#888888'
392         // close the meta tag
393         /**#@-*/
394     },
395 
396     /* precision options */
397     precision : {
398         touch    : 30,
399         mouse    : 4,
400         epsilon  : 0.0001,
401         hasPoint : 4
402     },
403 
404     /* Default ordering of the layers */
405     layer : {
406         numlayers: 20, // only important in SVG
407         text  : 9,
408         point : 9,   
409         arc   : 8,
410         line  : 7,
411         circle: 6, 
412         curve : 5,
413 		turtle : 5,
414         polygon: 3,
415         sector: 3,
416         angle : 3, 
417         integral : 3,
418         axis : 2,
419         grid  : 1,
420         image : 0,
421         trace: 0
422     },
423 
424     /**
425      * element type specific options 
426      */ 
427     /* special angle options */
428     angle : {
429         withLabel: true,
430 
431         /**
432          * Radius of the sector, displaying the angle.
433          * @type Number
434          * @name Angle#radius
435          */
436         radius : 1.0,
437         type : 'auto',  // 'square' or 'sector' or 'auto'
438         fillColor : '#FF7F00',
439         highlightFillColor : '#FF7F00',
440         strokeColor : '#FF7F00',
441         fillOpacity : 0.3,
442         highlightFillOpacity : 0.3,
443         radiuspoint: {
444             withLabel: false,
445             visible: false,
446             name: ''
447         },
448         pointsquare: {
449             withLabel: false,
450             visible: false,
451             name: ''
452         },
453         dot: {
454             visible: false,
455             strokeColor: 'none',
456             fillColor: 'black',
457             size: 2,
458             face: 'o',
459             withLabel: false,
460             name: ''
461         },
462         label: {
463             strokeColor: '#0000FF'
464         }
465     },
466 
467     /* special arc options */
468     arc : {
469         firstArrow : false,
470         lastArrow : false,
471         fillColor : 'none',
472         highlightFillColor : 'none',
473         strokeColor : '#0000ff',
474         highlightStrokeColor : '#C3D9FF',
475         useDirection: false
476     },
477 
478     /* special axis options */
479     axis: {
480         needsRegularUpdate : false,         // Axes only updated after zooming and moving of the origin.
481         strokeWidth: 1,
482         strokeColor : '#666666',
483         highlightStrokeWidth: 1,
484         highlightStrokeColor : '#888888',
485         withTicks: true,
486         straightFirst : true,
487         straightLast : true,
488         lastArrow: true,
489         withLabel: false, 
490         /* line ticks options */
491         ticks : {
492             needsRegularUpdate : false,            
493             strokeWidth: 1,
494             strokeColor : '#666666',
495             highlightStrokeColor : '#888888',
496             drawLabels : true,
497             drawZero : false,
498             insertTicks : true,
499             minTicksDistance : 10,
500             minorHeight : 4,          // if <0: full width and height
501             majorHeight : -1,         // if <0: full width and height
502             minorTicks : 4,
503             ticksDistance: 1,         // TODO doc
504             strokeOpacity : 0.25
505         },
506         point1 : {                  // Default values for point1 if created by line
507             needsRegularUpdate : false
508         },
509         point2 : {                  // Default values for point2 if created by line
510             needsRegularUpdate : false
511         },
512         label: {
513             position: 'lft',
514             offsets: [10,-20]
515         }
516     },
517     
518     /* special options for bisector of 3 points */
519     bisector : {
520         strokeColor: '#000000', // Bisector line
521         point : {               // Bisector point
522             visible: false,
523             fixed: false,
524             withLabel: false,
525             name: ''
526         }
527     },
528 
529     /* special options for the 2 bisectors of 2 lines */
530     bisectorlines : {
531         line1 : {               // 
532             strokeColor: 'red'
533         },
534         line2 : {               // 
535             strokeColor: 'black'
536         }
537     },
538 
539     /* special chart options */
540     chart: {
541         chartStyle: 'line',
542         colors: ['#B02B2C','#3F4C6B','#C79810','#D15600','#FFFF88','#C3D9FF','#4096EE','#008C00'],
543         highlightcolors: null,
544         fillcolor: null,
545         highlightonsector: false,
546         highlightbysize: false
547     },
548 
549     /*special circle options */
550     circle : {
551         fillColor : 'none',
552         highlightFillColor : 'none',
553         strokeColor : '#0000ff',
554         highlightStrokeColor : '#C3D9FF',
555         center: {
556             visible: false,
557             withLabel: false,
558             fixed: false,
559             name: ''
560         },
561         label: {
562             position: 'ulft'
563         }
564     },
565 
566     /* special options for circumcircle of 3 points */
567     circumcircle : {
568         fillColor : 'none',
569         highlightFillColor : 'none',
570         strokeColor : '#0000ff',
571         highlightStrokeColor : '#C3D9FF',
572         center : {               // center point
573             visible: false,
574             fixed: false,
575             withLabel: false,
576             name: ''
577         }
578     },
579 
580     circumcirclearc : {
581         fillColor : 'none',
582         highlightFillColor : 'none',
583         strokeColor : '#0000ff',
584         highlightStrokeColor : '#C3D9FF',
585         center: {
586             visible: false,
587             withLabel: false,
588             fixed: false,
589             name: ''
590         }
591     },
592 
593     /* special options for circumcircle sector of 3 points */
594     circumcirclesector: {
595         useDirection: true,
596         fillColor: '#00FF00',
597         highlightFillColor: '#00FF00',
598         fillOpacity: 0.3,
599         highlightFillOpacity: 0.3,
600         strokeColor : '#0000ff',
601         highlightStrokeColor : '#C3D9FF',
602         point: {
603             visible: false,
604             fixed: false,
605             withLabel: false,
606             name: ''
607         }
608     },
609     
610     /* special conic options */
611     conic : {
612         fillColor : 'none',
613         highlightFillColor : 'none',
614         strokeColor : '#0000ff',
615         highlightStrokeColor : '#C3D9FF',
616         foci: {
617             // points
618             fixed: false,
619             visible: false,
620             withLabel: false,
621             name: ''
622         }
623     },
624 
625     /* special curve options */
626     curve : {
627         strokeWidth : 1,
628         strokeColor : '#0000ff',
629         fillColor: 'none',
630         
631         /**#@+
632          * @visprop
633          */
634 
635        /**
636         * The data points of the curve are not connected with straight lines but with bezier curves.
637         * @name JXG.Curve#handDrawing
638         * @type Boolean
639         * @default false
640         */
641         handDrawing: false,
642 
643         /**
644          * The curveType is set in @see generateTerm and used in {@link JXG.Curve#updateCurve}.
645          * Possible values are <ul>
646          * <li>'none'</li>
647          * <li>'plot': Data plot</li>
648          * <li>'parameter': we can not distinguish function graphs and parameter curves</li>
649          * <li>'functiongraph': function graph</li>
650          * <li>'polar'</li>
651          * <li>'implicit' (not yet)</li></ul>
652          * Only parameter and plot are set directly. Polar is set with setProperties only.
653          * @name JXG.Curve#curveType
654          */
655         curveType: null,
656         RDPsmoothing : false,     // Apply the Ramer-Douglas-Peuker algorithm
657         numberPointsHigh : 1600,  // Number of points on curves after mouseUp
658         numberPointsLow : 400,    // Number of points on curves after mousemove
659         doAdvancedPlot : true,    // Use the algorithm by Gillam and Hohenwarter
660                                  // It is much slower, but the result is better
661         
662         label: {
663             position: 'lft'
664         }
665 
666         /**#@-*/
667     },
668 
669     glider: {},
670 
671     /* special grid options */
672     grid : {
673         /**#@+
674          * @visprop
675          */
676 
677         /* grid styles */
678         needsRegularUpdate : false,
679         hasGrid : false,
680         gridX : 1,
681         gridY : 1,
682         strokeColor : '#C0C0C0',
683         strokeOpacity : '0.5',
684         strokeWidth: 1,
685         dash : 0,    // dashed grids slow down the iPad considerably
686         /* snap to grid options */
687         
688         /**
689          * @deprecated
690          */
691         snapToGrid : false,
692         /**
693          * @deprecated
694          */
695         snapSizeX : 10,
696         /**
697          * @deprecated
698          */
699         snapSizeY : 10
700 
701         /**#@-*/
702     },
703 
704     /* special grid options */
705     image: {
706         imageString : null,
707         fillOpacity: 1.0
708     },
709     
710     /* special options for incircle of 3 points */
711     incircle : {
712         fillColor : 'none',
713         highlightFillColor : 'none',
714         strokeColor : '#0000ff',
715         highlightStrokeColor : '#C3D9FF',
716         center : {               // center point
717             visible: false,
718             fixed: false,
719             withLabel: false,
720             name: ''
721         }
722     },
723 
724     /* special options for integral */
725     integral: {
726         withLabel: true,    // Show integral value as text
727         strokeWidth: 0,
728         strokeOpacity: 0,
729         fillOpacity: 0.8,
730         curveLeft: {    // Start point
731             visible: true,
732             layer: 9
733         },
734         baseLeft: {    // Start point
735             visible: false,
736             fixed: false,
737             withLabel: false,
738             name: ''
739         },
740         curveRight: {      // End point
741             visible: true,
742             layer: 9
743         },
744         baseRight: {      // End point
745             visible: false,
746             fixed: false,
747             withLabel: false,
748             name: ''
749         },
750         label: {
751             fontSize: 20
752         }
753     },
754 
755     /* special legend options */
756     label: {
757         strokeColor: 'black',
758         
759         fixed: true,
760         /**
761          * Possible stirng values for the position of a label for
762          * label anchor points are:
763          * 'lft'|'rt'|'top'|'bot'|'ulft'|'urt'|'llft'|'lrt'
764          * This is relevant for non-points: line, circle, curve.
765          * @type String
766          * @default 'urt'
767          * @name JXG.GeometryElement#label.position
768          */
769         position: 'urt',
770         
771         /**
772         *  Label offsets from label anchor 
773         *  The label anchor is determined by JXG.GeometryElement#label.position
774         * @type Array
775         * @default [10,10]
776         * @name JXG.GeometryElement#label.offsets
777         **/
778         offsets: [10, 10]
779     },
780         
781     /* special legend options */
782     legend: {
783         /**
784          * @visprop
785          */
786         style: 'vertical',
787         labels: ['1','2','3','4','5','6','7','8'],
788         colors: ['#B02B2C','#3F4C6B','#C79810','#D15600','#FFFF88','#C3D9FF','#4096EE','#008C00']
789     },
790 
791     /* special line options */
792     line : {
793         /**#@+
794          * @visprop
795          */
796 
797         firstArrow : false,
798         lastArrow : false,
799         straightFirst : true,
800         straightLast : true,
801         fillColor : 'none',               // Important for VML on IE
802         highlightFillColor : 'none',  // Important for VML on IE
803         strokeColor : '#0000ff',
804         highlightStrokeColor : '#888888',
805         withTicks: false,
806 
807         /**#@-*/
808 
809         point1 : {                  // Default values for point1 if created by line
810             visible: false, 
811             withLabel: false, 
812             fixed: false,
813             name: ''
814         },
815         point2 : {                  // Default values for point2 if created by line
816             visible: false, 
817             withLabel: false, 
818             fixed: false,
819             name: ''
820         },
821         ticks : {
822             drawLabels : true,
823             drawZero : false,
824             insertTicks : false,
825             minTicksDistance : 50,
826             maxTicksDistance : 300,
827             minorHeight : 4,          // if <0: full width and height
828             majorHeight : -1,         // if <0: full width and height
829             minorTicks : 4,
830             defaultDistance : 1,
831             strokeOpacity : 0.3
832         },
833         
834         label: {
835             position:'llft'
836         }
837 
838     },
839 
840     /* special options for locus curves */
841     locus : {
842         /**#@+
843          * @visprop
844          */
845 
846         translateToOrigin: false,
847         translateTo10: false,
848         stretch: false,
849         toOrigin: null,
850         to10: null
851 
852         /**#@-*/
853     },
854     
855     /* special options for normal lines */
856     normal : {
857         strokeColor: '#000000', //  normal line
858         point : {
859             visible: false,
860             fixed: false,
861             withLabel: false,
862             name: ''
863         }
864     },
865 
866     /* special options for orthogonal projectionn points */
867     orthogonalprojection : {
868     }, 
869     
870     /* special options for parallel lines */
871     parallel : {
872         strokeColor: '#000000', // Parallel line
873         point : {
874             visible: false,
875             fixed: false,
876             withLabel: false,
877             name: ''
878         }
879     },
880 
881     /* special perpendicular options */
882     perpendicular : {
883         strokeColor: '#000000', // Perpendicular line
884         straightFirst: true,
885         straightLast: true
886     },
887 
888     /* special perpendicular options */
889     perpendicularsegment : {
890         strokeColor: '#000000', // Perpendicular segment
891         straightFirst: false,
892         straightLast: false,
893         point : {               // Perpendicular point
894             visible: false,
895             fixed: true,
896             withLabel: false,
897             name: ''
898         }
899     },
900 
901     /* special point options */
902     point : {
903         /**#@+
904          * @visprop
905          */
906 
907     	withLabel: true,
908 
909         /**
910          * This attribute was used to determined the point layout. It was derived from GEONExT and was
911          * replaced by {@link JXG.Point#face} and {@link JXG.Point#size}.
912          * @see JXG.Point#face
913          * @see JXG.Point#size
914          * @type Number
915          * @default JXG.Options.point#style
916          * @name JXG.Point#style
917          * @deprecated
918          */
919         style : 5,
920 
921         /**
922          * There are different point styles which differ in appearance.
923          * Posssible values are
924          * <table><tr><th>Value</th></tr>
925          * <tr><td>cross</td></tr>
926          * <tr><td>circle</td></tr>
927          * <tr><td>square</td></tr>
928          * <tr><td>plus</td></tr>
929          * <tr><td>diamond</td></tr>
930          * <tr><td>triangleUp</td></tr>
931          * <tr><td>triangleDown</td></tr>
932          * <tr><td>triangleLeft</td></tr>
933          * <tr><td>triangleRight</td></tr>
934          * </table>
935          * @type string
936          * @see JXG.Point#setStyle
937          * @default circle
938          * @name JXG.Point#face
939          */
940         face : 'o',
941 
942         /**
943          * Determines the size of a point.
944          * Means radius resp. half the width of a point (depending on the face).
945          * @see JXG.Point#face
946          * @type number
947          * @see JXG.Point#setStyle
948          * @default 3
949          * @name JXG.Point#size
950          */
951         size : 3,
952         fillColor : '#ff0000',
953         highlightFillColor : '#EEEEEE',
954         strokeWidth: 2,
955         strokeColor : '#ff0000',
956         highlightStrokeColor : '#C3D9FF',
957         zoom: false,             // Change the point size on zoom
958 
959         /**
960          * If true, the infobox is shown on mouse over, else not.
961          * @name JXG.Point#showInfobox
962          * @type Boolean
963          * @default true
964          */
965         showInfobox: true,
966 
967         draft: false,
968         
969         /**
970          * List of attractor elements. If the distance of the point is less than
971          * attractorDistance the point is made to glider of this element.
972          * @type array
973          * @name JXG.Point#attractors
974          * @default empty
975          */
976         attractors: [],
977         
978         /**
979          * If the distance of the point to one of its attractors is less 
980          * than this number the point will be a glider on this 
981          * attracting element. 
982          * If set to zero nothing happens.
983          * @type number
984          * @name JXG.Point#attractorDistance
985          * @default 0
986          */
987         attractorDistance: 0.0,
988         
989         /**
990          * If the distance of the point to one of its attractors is at least 
991          * this number the point will be released from being a glider on the
992          * attracting element. 
993          * If set to zero nothing happens.
994          * @type number
995          * @name JXG.Point#snatchDistance
996          * @default 0
997          */
998         snatchDistance: 0.0,
999         
1000         /**
1001          * If set to true, the point will snap to a grid defined by
1002          * {@link JXG.Point#snapSizeX} and {@link JXG.Point#snapSizeY}.
1003          * @see JXG.Point#snapSizeX
1004          * @see JXG.Point#snapSizeY
1005          * @type Boolean
1006          * @name JXG.Point#snapToGrid
1007          * @default false
1008          */
1009         snapToGrid: false,
1010 
1011         /**
1012          * Defines together with {@link JXG.Point#snapSizeY} the grid the point snaps on to.
1013          * The point will only snap on values multiple to snapSizeX in x and snapSizeY in y direction.
1014          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
1015          * of the default ticks of the default x axes of the board.
1016          * @see JXG.Point#snapToGrid
1017          * @see JXG.Point#snapSizeY
1018          * @see JXG.Board#defaultAxes
1019          * @type Number
1020          * @name JXG.Point#snapSizeX
1021          * @default 1
1022          */
1023         snapSizeX: 1,
1024 
1025         /**
1026          * Defines together with {@link JXG.Point#snapSizeX} the grid the point snaps on to.
1027          * The point will only snap on values multiple to snapSizeX in x and snapSizeY in y direction.
1028          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
1029          * of the default ticks of the default y axes of the board.
1030          * @see JXG.Point#snapToGrid
1031          * @see JXG.Point#snapSizeX
1032          * @see JXG.Board#defaultAxes
1033          * @type Number
1034          * @name JXG.Point#snapSizeY
1035          * @default 1
1036          */
1037         snapSizeY: 1,
1038 
1039         /**
1040          * If set to true, the point will snap to the nearest point in distance of 
1041          * {@link JXG.Point#attractorDistance}. 
1042          * @see JXG.Point#attractorDistance
1043          * @type Boolean
1044          * @name JXG.Point#snapToPoints
1045          * @default false
1046          */
1047         snapToPoints: false
1048 
1049         /**#@-*/
1050     },
1051 
1052     /* special polygon options */
1053     polygon : {
1054         /**#@+
1055          * @visprop
1056          */
1057 
1058         /**
1059          * If <tt>true</tt>, moving the mouse over inner points triggers hasPoint.
1060          * @see JXG.GeometryElement#hasPoint
1061          * @name JXG.Polygon#hasInnerPoints
1062          * @type Boolean
1063          * @default false
1064          */
1065         hasInnerPoints: false,
1066         fillColor : '#00FF00',
1067         highlightFillColor : '#00FF00',
1068         fillOpacity : 0.3,
1069         highlightFillOpacity : 0.3,
1070 
1071         /**
1072          * Is the polygon bordered by lines?
1073          * @type Boolean
1074          * @name JXG.Polygon#withLines
1075          * @default true
1076          */
1077         withLines: true,
1078 
1079         /**#@-*/
1080 
1081         borders: {
1082             withLabel: false,
1083 		    strokeWidth: 1,
1084 		    highlightStrokeWidth: 1,
1085             // Polygon layer + 1
1086             layer: 5
1087         },
1088         
1089         /**
1090          *  Points for regular polygons
1091          */ 
1092         vertices : {
1093             withLabel: true,
1094             strokeColor: '#ff0000',
1095             fillColor: '#ff0000',
1096             fixed: true
1097         },
1098         
1099         label: {
1100             offsets: [0,0]
1101         }
1102     },
1103 
1104     /* special options for riemann sums */
1105     riemannsum: {
1106         withLabel:false,
1107         fillOpacity:0.3,
1108         fillColor:'#ffff00'
1109     },
1110 
1111     /* special sector options */
1112     sector : {
1113         fillColor: '#00FF00',
1114         highlightFillColor: '#00FF00',
1115         fillOpacity: 0.3,
1116         highlightFillOpacity: 0.3
1117     },
1118 
1119     semicircle : {
1120         midpoint: {
1121             visible: false,
1122             withLabel: false,
1123             fixed: false,
1124             name: ''
1125         }
1126     },
1127 
1128     /* special slider options */
1129     slider : {
1130         /**#@+
1131          * @visprop
1132          */
1133 
1134         /**
1135          * The slider only returns multiples of this value, e.g. for discrete values set this property to <tt>1</tt>. For
1136          * continuous results set this to <tt>-1</tt>.
1137          * @memberOf Slider.prototype
1138          * @name snapWidth
1139          * @type Number
1140          */
1141         snapWidth: -1,      // -1 = deactivated
1142 
1143         /**
1144          * The precision of the slider value displayed in the optional text.
1145          * @memberOf Slider.prototype
1146          * @name precision
1147          * @type Number
1148          */
1149         precision: 2,
1150         firstArrow : false,
1151         lastArrow : false,
1152         withTicks: true,
1153         withLabel: true,
1154 
1155         layer: 9,
1156         showInfobox: false,
1157         name : '',
1158         visible: true,
1159         strokeColor : '#000000',
1160         highlightStrokeColor : '#888888',
1161         fillColor : '#ffffff',
1162         highlightFillColor : 'none',
1163         size: 6,
1164 
1165         /**#@-*/
1166             
1167         point1: {
1168             needsRegularUpdate : false,
1169             showInfobox: false,
1170             withLabel: false,
1171             visible: false,
1172             fixed: true,
1173             name: ''
1174         },
1175         point2: {
1176             needsRegularUpdate : false,
1177             showInfobox: false,
1178             withLabel: false,
1179             visible: false,
1180             fixed: true,
1181             name: ''
1182         },
1183         baseline: {
1184             needsRegularUpdate : false,
1185             name : '',
1186             strokeWidth: 1,
1187             strokeColor : '#000000',
1188             highlightStrokeColor : '#888888'
1189         },
1190         /* line ticks options */
1191         ticks : {
1192             needsRegularUpdate : false,
1193             drawLabels : false,
1194             drawZero : true,
1195             insertTicks : true,
1196             minorHeight : 4,          // if <0: full width and height
1197             majorHeight : 10,        // if <0: full width and height
1198             minorTicks : 0,
1199             defaultDistance : 1,
1200             strokeOpacity : 1,
1201             strokeWidth: 1,
1202             strokeColor : '#000000'
1203         }, 
1204         highline: {
1205             strokeWidth: 3,
1206             name : '',
1207             strokeColor : '#000000',
1208             highlightStrokeColor : '#888888'
1209         },
1210         label: {
1211             strokeColor: '#000000'
1212         }
1213     },
1214     
1215     /* special text options */
1216     text : {
1217         /**#@+
1218          * @visprop
1219          */
1220 
1221         fontSize : 12,
1222         digits: 2,
1223         isLabel: false,
1224         strokeColor : '#000000',
1225         useASCIIMathML : false,
1226         useMathJax : false,
1227         display : 'html',                    //'html' or 'internal'
1228         cssClass : 'JXGtext',
1229         highlightCssClass : 'JXGtext',
1230         withLabel: false
1231 
1232         /**#@-*/
1233     },
1234     
1235     /* special options for trace curves */
1236     tracecurve : {
1237         /**#@+
1238          * @visprop
1239          */
1240         strokeColor: '#000000',
1241         fillColor: 'none',
1242         numberPoints: 100
1243 
1244         /**#@-*/
1245     },
1246 
1247     /*special turtle options */
1248     turtle : {
1249         strokeWidth : 1,
1250 		fillColor: 'none',
1251 		strokeColor: '#000000',
1252 		arrow : {
1253 			strokeWidth: 2,
1254 			withLabel: false,
1255 			strokeColor: '#ff0000'
1256 		}
1257     },
1258 
1259 
1260     /**
1261       * Abbreviations of properties. Setting the shortcut means setting abbreviated properties
1262       * to the same value.
1263       * It is used in JXG.GeometryElement#setProperty and in
1264       * the constructor JXG.GeometryElement.
1265       * Attention: In Options.js abbreviations are not allowed.
1266       */
1267     shortcuts : {
1268         color: ['strokeColor', 'fillColor'],
1269         opacity: ['strokeOpacity', 'fillOpacity'],
1270         highlightColor: ['highlightStrokeColor', 'highlightFillColor'],
1271         highlightOpacity: ['highlightStrokeOpacity', 'highlightFillOpacity'],
1272         strokeWidth: ['strokeWidth', 'highlightStrokeWidth']
1273     }
1274     
1275 };
1276 
1277 /**
1278  * Holds all possible properties and the according validators for geometry elements. A validator is either a function
1279  * which takes one parameter and returns true, if the value is valid for the property, or it is false if no validator
1280  * is required.
1281  */
1282 JXG.Validator = (function () {
1283     var validatePixel = function (v) {
1284             return /^[0-9]+px$/.test(v);
1285         },
1286         validateDisplay = function (v) {
1287             return (v  in {html: 0, internal: 0});
1288         },
1289         validateColor = function (v) {
1290             // for now this should do it...
1291             return JXG.isString(v);
1292         },
1293         validatePointFace = function (v) {
1294             return JXG.exists(JXG.Point.prototype.normalizeFace.call(this, v));
1295         },
1296         validateInteger = function (v) {
1297             return (Math.abs(v - Math.round(v)) < JXG.Math.eps);
1298         },
1299         validatePositiveInteger = function (v) {
1300             return validateInteger(v) && v > 0;
1301         },
1302         validateScreenCoords = function (v) {
1303             return v.length >= 2 && validateInteger(v[0]) && validateInteger(v[1]);
1304         },
1305         validateRenderer = function (v) {
1306             return (v in {vml: 0, svg: 0, canvas: 0});
1307         },
1308         validatePositive = function (v) {
1309             return v > 0;
1310         },
1311         validateNotNegative = function (v) {
1312             return !(v < 0);
1313         },
1314     i, v = {},
1315     validators = {
1316         attractorDistance: validateNotNegative,
1317         color: validateColor,
1318         defaultDistance: JXG.isNumber,
1319         display : validateDisplay,
1320         doAdvancedPlot: false,
1321         draft : false,
1322         drawLabels : false,
1323         drawZero : false,
1324         face : validatePointFace,
1325         factor : JXG.isNumber,
1326         fillColor: validateColor,
1327         fillOpacity : JXG.isNumber,
1328         firstArrow : false,
1329         fontSize : validateInteger,
1330         dash : validateInteger,
1331         gridX : JXG.isNumber,
1332         gridY : JXG.isNumber,
1333         hasGrid : false,
1334         highlightFillColor: validateColor,
1335         highlightFillOpacity: JXG.isNumber,
1336         highlightStrokeColor: validateColor,
1337         highlightStrokeOpacity: JXG.isNumber,
1338         insertTicks : false,
1339         //: validateScreenCoords,
1340         lastArrow : false,
1341         majorHeight : validateInteger,
1342         maxTicksDistance : validatePositiveInteger,
1343         minorHeight : validateInteger,
1344         minorTicks : validatePositiveInteger,
1345         minTicksDistance : validatePositiveInteger,
1346         numberPointsHigh : validatePositiveInteger,
1347         numberPointsLow : validatePositiveInteger,
1348         opacity : JXG.isNumber,
1349         radius : JXG.isNumber,
1350         RDPsmoothing : false,
1351         renderer: validateRenderer,
1352         right: validatePixel,
1353         showCopyright : false,
1354         showInfobox: false,
1355         showNavigation : false,
1356         size : validateInteger,
1357         snapSizeX : validatePositive,
1358         snapSizeY : validatePositive,
1359         snapWidth : JXG.isNumber,
1360         snapToGrid : false,
1361         snatchDistance: validateNotNegative,
1362         straightFirst : false,
1363         straightLast : false,
1364         stretch: false,
1365         strokeColor : validateColor,
1366         strokeOpacity: JXG.isNumber,
1367         strokeWidth : validateInteger,
1368         takeFirst : false,
1369         takeSizeFromFile : false,
1370         to10: false,
1371         toOrigin: false,
1372         translateTo10: false,
1373         translateToOrigin: false,
1374         useASCIIMathML : false,
1375         useDirection: false,
1376         useMathJax : false,
1377         withLabel: false,
1378         withTicks: false,
1379         zoom: false
1380     };
1381 
1382     // this seems like a redundant step but it makes sure that
1383     // all properties in the validator object have lower case names
1384     // and the validator object is easier to read.
1385     for (i in validators) {
1386         v[i.toLowerCase()] = validators[i];
1387     }
1388 
1389     return v;
1390 })();
1391 
1392 
1393 /**
1394  * Apply the options stored in this object to all objects on the given board.
1395  * @param {JXG.Board} board The board to which objects the options will be applied.
1396  */
1397 JXG.useStandardOptions = function(board) {
1398     var o = JXG.Options,
1399         boardHadGrid = board.hasGrid,
1400         el, t, p, copyProps;
1401 
1402     board.options.grid.hasGrid = o.grid.hasGrid;
1403     board.options.grid.gridX = o.grid.gridX;
1404     board.options.grid.gridY = o.grid.gridY;
1405     board.options.grid.gridColor = o.grid.gridColor;
1406     board.options.grid.gridOpacity = o.grid.gridOpacity;
1407     board.options.grid.gridDash = o.grid.gridDash;
1408     board.options.grid.snapToGrid = o.grid.snapToGrid;
1409     board.options.grid.snapSizeX = o.grid.SnapSizeX;
1410     board.options.grid.snapSizeY = o.grid.SnapSizeY;
1411     board.takeSizeFromFile = o.takeSizeFromFile;
1412 
1413     copyProps = function(p, o) {
1414             p.visProp.fillcolor = o.fillColor;
1415             p.visProp.highlightfillcolor = o.highlightFillColor;
1416             p.visProp.strokecolor = o.strokeColor;
1417             p.visProp.highlightstrokecolor = o.highlightStrokeColor;
1418     };
1419     
1420     for(el in board.objects) {
1421         p = board.objects[el];
1422         if(p.elementClass == JXG.OBJECT_CLASS_POINT) {
1423             copyProps(p, o.point);
1424         }
1425         else if(p.elementClass == JXG.OBJECT_CLASS_LINE) {
1426             copyProps(p, o.line);
1427             for(t in p.ticks) {
1428                 t.majorTicks = o.line.ticks.majorTicks;
1429                 t.minTicksDistance = o.line.ticks.minTicksDistance;
1430                 t.visProp.minorheight = o.line.ticks.minorHeight;
1431                 t.visProp.majorheight = o.line.ticks.majorHeight;
1432             }
1433         }
1434         else if(p.elementClass == JXG.OBJECT_CLASS_CIRCLE) {
1435             copyProps(p, o.circle);
1436         }
1437         else if(p.type == JXG.OBJECT_TYPE_ANGLE) {
1438             copyProps(p, o.angle);
1439         }
1440         else if(p.type == JXG.OBJECT_TYPE_ARC) {
1441             copyProps(p, o.arc);
1442         }
1443         else if(p.type == JXG.OBJECT_TYPE_POLYGON) {
1444             copyProps(p, o.polygon);
1445         }
1446         else if(p.type == JXG.OBJECT_TYPE_CONIC) {
1447             copyProps(p, o.conic);
1448         }
1449         else if(p.type == JXG.OBJECT_TYPE_CURVE) {
1450             copyProps(p, o.curve);
1451         }
1452         else if(p.type == JXG.OBJECT_TYPE_SECTOR) {
1453             p.arc.visProp.fillcolor = o.sector.fillColor;
1454             p.arc.visProp.highlightfillcolor = o.sector.highlightFillColor;
1455             p.arc.visProp.fillopacity = o.sector.fillOpacity;
1456             p.arc.visProp.highlightfillopacity = o.sector.highlightFillOpacity;
1457         }
1458     }
1459 
1460     board.fullUpdate();
1461     if(boardHadGrid && !board.hasGrid) {
1462         board.removeGrids(board);
1463     } else if(!boardHadGrid && board.hasGrid) {
1464         board.create('grid', []);
1465     }
1466 };
1467 
1468 /**
1469  * Converts all color values to greyscale and calls useStandardOption to put them onto the board.
1470  * @param {JXG.Board} board The board to which objects the options will be applied.
1471  * @see #useStandardOptions
1472  */
1473 JXG.useBlackWhiteOptions = function(board) {
1474     var o = JXG.Options;
1475     o.point.fillColor = JXG.rgb2bw(o.point.fillColor);
1476     o.point.highlightFillColor = JXG.rgb2bw(o.point.highlightFillColor);
1477     o.point.strokeColor = JXG.rgb2bw(o.point.strokeColor);
1478     o.point.highlightStrokeColor = JXG.rgb2bw(o.point.highlightStrokeColor);
1479 
1480     o.line.fillColor = JXG.rgb2bw(o.line.fillColor);
1481     o.line.highlightFillColor = JXG.rgb2bw(o.line.highlightFillColor);
1482     o.line.strokeColor = JXG.rgb2bw(o.line.strokeColor);
1483     o.line.highlightStrokeColor = JXG.rgb2bw(o.line.highlightStrokeColor);
1484 
1485     o.circle.fillColor = JXG.rgb2bw(o.circle.fillColor);
1486     o.circle.highlightFillColor = JXG.rgb2bw(o.circle.highlightFillColor);
1487     o.circle.strokeColor = JXG.rgb2bw(o.circle.strokeColor);
1488     o.circle.highlightStrokeColor = JXG.rgb2bw(o.circle.highlightStrokeColor);
1489 
1490     o.arc.fillColor = JXG.rgb2bw(o.arc.fillColor);
1491     o.arc.highlightFillColor = JXG.rgb2bw(o.arc.highlightFillColor);
1492     o.arc.strokeColor = JXG.rgb2bw(o.arc.strokeColor);
1493     o.arc.highlightStrokeColor = JXG.rgb2bw(o.arc.highlightStrokeColor);
1494 
1495     o.polygon.fillColor = JXG.rgb2bw(o.polygon.fillColor);
1496     o.polygon.highlightFillColor  = JXG.rgb2bw(o.polygon.highlightFillColor);
1497 
1498     o.sector.fillColor = JXG.rgb2bw(o.sector.fillColor);
1499     o.sector.highlightFillColor  = JXG.rgb2bw(o.sector.highlightFillColor);
1500 
1501     o.curve.strokeColor = JXG.rgb2bw(o.curve.strokeColor);
1502     o.grid.gridColor = JXG.rgb2bw(o.grid.gridColor);
1503 
1504     JXG.useStandardOptions(board);
1505 };
1506