1 /*global JXG: true, define: true, escape: true, unescape: true*/
  2 /*jslint nomen: true, plusplus: true, bitwise: true*/
  3 
  4 /* depends:
  5  jxg
  6  */
  7 
  8 define(['jxg'], function (JXG) {
  9 
 10     "use strict";
 11 
 12     // constants
 13     var UTF8_ACCEPT = 0,
 14         UTF8_REJECT = 12,
 15         UTF8D = [
 16             // The first part of the table maps bytes to character classes that
 17             // to reduce the size of the transition table and create bitmasks.
 18             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 19             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 20             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 21             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 22             1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,   9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
 23             7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,   7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 24             8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 25             10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3,  11, 6, 6, 6, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 26 
 27             // The second part is a transition table that maps a combination
 28             // of a state of the automaton and a character class to a state.
 29             0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72,  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
 30             12,  0, 12, 12, 12, 12, 12,  0, 12,  0, 12, 12,  12, 24, 12, 12, 12, 12, 12, 24, 12, 24, 12, 12,
 31             12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12,  12, 24, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12,
 32             12, 12, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12,  12, 36, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12,
 33             12, 36, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
 34         ];
 35 
 36     // Util namespace
 37     JXG.Util = JXG.Util || {};
 38 
 39     /**
 40      * UTF8 encoding routines
 41      * @namespace
 42      */
 43     JXG.Util.UTF8 = {
 44         /**
 45          * Encode a string to utf-8.
 46          * @param {String} string
 47          * @return {String} utf8 encoded string
 48          */
 49         encode : function (string) {
 50             var n, c,
 51                 utftext = '',
 52                 len = string.length;
 53 
 54             string = string.replace(/\r\n/g, '\n');
 55 
 56             // See
 57             // http://ecmanaut.blogspot.ca/2006/07/encoding-decoding-utf8-in-javascript.html
 58             // http://monsur.hossa.in/2012/07/20/utf-8-in-javascript.html
 59             if (typeof unescape === 'function' && typeof encodeURIComponent === 'function') {
 60                 return unescape(encodeURIComponent(string));
 61             }
 62 
 63             for (n = 0; n < len; n++) {
 64                 c = string.charCodeAt(n);
 65 
 66                 if (c < 128) {
 67                     utftext += String.fromCharCode(c);
 68                 } else if ((c > 127) && (c < 2048)) {
 69                     utftext += String.fromCharCode((c >> 6) | 192);
 70                     utftext += String.fromCharCode((c & 63) | 128);
 71                 } else {
 72                     utftext += String.fromCharCode((c >> 12) | 224);
 73                     utftext += String.fromCharCode(((c >> 6) & 63) | 128);
 74                     utftext += String.fromCharCode((c & 63) | 128);
 75                 }
 76 
 77             }
 78 
 79             return utftext;
 80         },
 81 
 82         /**
 83          * Decode a string from utf-8.
 84          * @param {String} utftext to decode
 85          * @return {String} utf8 decoded string
 86          */
 87         decode : function (utftext) {
 88 
 89             /*
 90                  The following code is a translation from C99 to JavaScript.
 91 
 92                  The original C99 code can be found at
 93                  http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
 94 
 95                  Original copyright note:
 96 
 97                  Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
 98 
 99                  License: MIT License (see LICENSE.MIT)
100             */
101 
102             var i, byte, type, char,
103                 codep = 0,
104                 state = UTF8_ACCEPT,
105                 string = [],
106                 len = utftext.length;
107 
108             for (i = 0; i < len; i++) {
109                 byte = utftext.charCodeAt(i);
110                 type = UTF8D[byte];
111 
112                 if (state !== UTF8_ACCEPT) {
113                     codep = (byte & 0x3f) | (codep << 6);
114                 } else {
115                     codep = (0xff >> type) & byte;
116                 }
117 
118                 state = UTF8D[256 + state + type];
119 
120                 if (state === UTF8_ACCEPT) {
121                     if (codep > 0xffff) {
122                         string.push(0xD7C0 + (codep >> 10), 0xDC00 + (codep & 0x3FF));
123                     } else {
124                         string.push(codep);
125                     }
126                 }
127             }
128 
129             return String.fromCharCode.apply(null, string);
130         },
131 
132         /**
133          * Extends the standard charCodeAt() method of the String class to find the ASCII char code of
134          * a character at a given position in a UTF8 encoded string.
135          * @param {String} str
136          * @param {Number} i position of the character
137          * @return {Number}
138          */
139         asciiCharCodeAt: function (str, i) {
140             var c = str.charCodeAt(i);
141 
142             if (c > 255) {
143                 switch (c) {
144                 case 8364:
145                     c = 128;
146                     break;
147                 case 8218:
148                     c = 130;
149                     break;
150                 case 402:
151                     c = 131;
152                     break;
153                 case 8222:
154                     c = 132;
155                     break;
156                 case 8230:
157                     c = 133;
158                     break;
159                 case 8224:
160                     c = 134;
161                     break;
162                 case 8225:
163                     c = 135;
164                     break;
165                 case 710:
166                     c = 136;
167                     break;
168                 case 8240:
169                     c = 137;
170                     break;
171                 case 352:
172                     c = 138;
173                     break;
174                 case 8249:
175                     c = 139;
176                     break;
177                 case 338:
178                     c = 140;
179                     break;
180                 case 381:
181                     c = 142;
182                     break;
183                 case 8216:
184                     c = 145;
185                     break;
186                 case 8217:
187                     c = 146;
188                     break;
189                 case 8220:
190                     c = 147;
191                     break;
192                 case 8221:
193                     c = 148;
194                     break;
195                 case 8226:
196                     c = 149;
197                     break;
198                 case 8211:
199                     c = 150;
200                     break;
201                 case 8212:
202                     c = 151;
203                     break;
204                 case 732:
205                     c = 152;
206                     break;
207                 case 8482:
208                     c = 153;
209                     break;
210                 case 353:
211                     c = 154;
212                     break;
213                 case 8250:
214                     c = 155;
215                     break;
216                 case 339:
217                     c = 156;
218                     break;
219                 case 382:
220                     c = 158;
221                     break;
222                 case 376:
223                     c = 159;
224                     break;
225                 default:
226                     break;
227                 }
228             }
229             return c;
230         }
231     };
232 
233     return JXG.Util.UTF8;
234 });
235