1 /**
  2  * @fileOverview
  3  * memory.enchant.js
  4  * @version 0.2.3 (2013/04/3)
  5  * @requires enchant.js v0.6.0 or later
  6  * @requires nineleap.enchant.js v0.2.2 or later
  7  * @author UEI Corporation
  8  *
  9  * @description
 10  * enchant.js extention for 9leap.net
 11  * @usage
 12  * EXAMPLE: use user memory
 13  * var core = new Core();
 14  * core.memory.player.preload();
 15  * core.onload = function () {
 16  *    var playerSp = this.memory.player.toSprite();
 17  *    playerSp.x = this.width / 2 - playerSp.width / 2;
 18  *    playerSp.y = this.height / 2 - playerSp.height / 2;
 19  *    this.rootScene.addChild(playerSp);
 20  * };
 21  * core.start();
 22  */
 23 
 24 (function() {
 25     enchant();
 26     /**
 27      * 依存ライブラリcheck
 28      */
 29     var parentModule;
 30     if (enchant.nineleap.twitter !== undefined &&
 31         Object.getPrototypeOf(enchant.nineleap.twitter) === Object.prototype) {
 32         parentModule = enchant.nineleap.twitter;
 33     } else if (enchant.nineleap !== undefined &&
 34         Object.getPrototypeOf(enchant.nineleap) === Object.prototype) {
 35         parentModule = enchant.nineleap;
 36     } else {
 37         throw new Error('Cannot load nineleap.enchant.js.');
 38     }
 39 
 40     /**
 41      * namespace object
 42      * @type {Object}
 43      */
 44     enchant.nineleap.memory = { assets: ['indicator.png'] };
 45 
 46     /**
 47      * ゲームメモリーリクエストが成功した時に発生するイベント.
 48      * 発行するオブジェクト: enchant.Core, enchant.Scene,
 49      * @type {String}
 50      */
 51     enchant.Event.COMPLETE_MEMORY_REQUEST = 'complete_memory_request';
 52 
 53 
 54     /**
 55      * ゲームメモリーリクエストのレスポンスがエラーの時に発生するイベント.
 56      * 発行するオブジェクト: enchant.Core, enchant.Scene,
 57      * @type {String}
 58      */
 59     enchant.Event.ERROR_MEMORY_REQUEST = 'error_memory_request';
 60 
 61     /**
 62      * ゲームメモリーのアップデートが完了したときに発生するイベント.
 63      * 発行するオブジェクト: enchant.Core, enchant.Scene,
 64      * @type {String}
 65      */
 66     enchant.Event.COMPLETE_UPDATE = 'complete_update';
 67 
 68     /**
 69      * XHRのreadyStateが4になった時に発生するイベント.
 70      * 発行するオブジェクト: enchant.Core, enchant.Scene, enchant.nineleap.memory.MemoryWrite,
 71      * @type {String}
 72      */
 73     enchant.Event.COMPLETE_XHR_REQUEST = 'complete_xhr_request';
 74 
 75     /**
 76      * XHRのreadyStateが1になった時に発生するイベント.
 77      * 発行するオブジェクト: enchant.Core, enchant.Scene, enchant.nineleap.memory.MemoryWrite,
 78      * @type {String}
 79      */
 80     enchant.Event.LOADING_XHR_REQUEST = 'loading_xhr_request';
 81 
 82     /**
 83      * XHRのreadyStateが2になった時に発生するイベント.
 84      * 発行するオブジェクト: enchant.Core, enchant.Scene, enchant.nineleap.memory.MemoryWrite,
 85      * @type {String}
 86      */
 87     enchant.Event.LOADED_XHR_REQUEST = 'loaded_xhr_request';
 88 
 89     /**
 90      * XHRのreadyDtateが3になった時に発生するイベント.
 91      * 発行するオブジェクト: enchant.Core, enchant.Scene, enchant.nineleap.memory.MemoryWrite,
 92      * @type {String}
 93      */
 94     enchant.Event.INTERACTIVE_XHR_REQUEST = 'interactive_xhr_request';
 95 
 96     /**
 97      * XHRのレスポンスがエラーの時に発生するイベント.
 98      * 発行するオブジェクト: enchant.Core, enchant.Scene, enchant.nineleap.memory.MemoryWrite,
 99      * @type {String}
100      */
101     enchant.Event.ERROR_XHR_REQUEST = 'error_xhr_request';
102 
103     /**
104      * @scope enchant.nineleap.memory.Core.prototype
105      */
106     enchant.nineleap.memory.Core = enchant.Class.create(parentModule.Core, {
107         /**
108          * メモリを扱うためのゲームオブジェクト
109          * @constructs
110          * @param width
111          * @param height
112          */
113         initialize: function(width, height) {
114             parentModule.Core.call(this, width, height);
115             this._memoryRequests = [];
116             this.requireAuth = true;
117             this.authorized = true;
118             this.memoryQueue = 0;
119             this.ajaxQueue = 0;
120             this._ajaxRequests = [];
121             this._memoryAssets = [];
122             this._memory = {
123                 user: {
124                     preload: enchant.nineleap.memory.Core.prototype.user_preload
125                 },
126                 player: {
127                     preload: enchant.nineleap.memory.Core.prototype.player_preload
128                 },
129                 update: enchant.nineleap.memory.Core.prototype.memory_update
130             };
131             this._memories = {
132                 friends: {
133                     preload: enchant.nineleap.memory.Core.prototype.friends_preload
134                 },
135                 ranking: {
136                     preload: enchant.nineleap.memory.Core.prototype.ranking_preload
137                 },
138                 recent: {
139                     preload: enchant.nineleap.memory.Core.prototype.recent_preload
140                 }
141             };
142             this.addEventListener('load', function() {
143                 this.ajaxloading = new SplashScene();
144                 this.ajaxloading.image = this.assets['indicator.png'];
145                 var core = this;
146                 this.ajaxloading.childNodes[0].addEventListener('enterframe', function() {
147                     if (core.frame % 5 == 0) this.rotate(16);
148                 });
149             });
150             this.addEventListener('enterframe', function() {
151                 if (this.ajaxQueue + this.memoryQueue && this.running) {
152                     if (this.currentScene != this.ajaxloading) this.pushScene(this.ajaxloading);
153                 } else {
154                     if (this.currentScene == this.ajaxloading) this.popScene();
155                 }
156             });
157         },
158 
159         start: function() {
160             if (this.memoryQueue != 0) {
161                 if (this._memoryRequests.length) {
162                     for (var i = 0, l = this._memoryRequests.length; i < l; i++) {
163                         this._memoryRequests[i]._sendRequest();
164                     }
165                 }
166                 return;
167             }
168             parentModule.Core.prototype.start.call(this);
169         },
170 
171         /**
172          * 格納しているデータ
173          * @type {*}
174          */
175         memory: {
176             get: function() {
177                 return this._memory;
178             },
179             set: function(data) {
180                 return this._memory = data;
181             }
182         },
183 
184         /**
185          * @type {*}
186          */
187         memories: {
188             get: function() {
189                 return this._memories;
190             },
191             set: function(data) {
192                 return this._memories = data;
193             }
194         },
195 
196         preloadMemory: function(requestType, option, checkError) {
197             if (arguments.length == 2) {
198                 if (typeof arguments[1] == 'boolean') {
199                     checkError = arguments[1];
200                     option = {};
201                 } else {
202                     checkError = true;
203                 }
204             } else if (arguments.length == 1) {
205                 option = {};
206                 checkError = true;
207             }
208             this.memoryQueue++;
209             if (enchant.nineleap.memory.LocalStorage.DEBUG_MODE) {
210                 var setmemory = (requestType.match(/user_memory/)) ? this.memory.player :
211                     (requestType.match(/u\/[0-9a-zA-Z_+]/)) ? this.memory.user[requestType.replace(/u\//, '')] :
212                         (requestType.match(/friends_memories/)) ? this.memories.friends :
213                             (requestType.match(/recent_memories/)) ? this.memories.recent :
214                                 (requestType.match(/ranking_memories/)) ? this.memories.ranking : null;
215                 var localstorage = new LocalStorage(LocalStorage.GAME_ID);
216                 var resBody = (requestType == 'user_memory') ? localstorage.get_user_memory('mine') :
217                     (requestType.match(/(friends|recent|ranking)_memories/)) ?
218                         localstorage.all_user_memories : (requestType.match(/$u\/.+/)) ?
219                         localstorage.get_user_memory(requestType.replace(/u\//, "")) : null;
220                 this.memoryQueue--;
221                 if (resBody == null) {
222                     setmemory.data = null;
223                     if (requestType == 'user_memory') setmemory.user = 'mine';
224                 } else {
225                     if (resBody instanceof Array) {
226                         for (var i = 0, l = resBody.length; i < l; i++) {
227                             if (resBody[i] instanceof Object) {
228                                 setmemory[i] = {};
229                                 this._pushData(resBody[i], setmemory[i]);
230                             } else setmemory[i] = resBody[i];
231                         }
232                         setmemory.length = l;
233                     } else if (resBody instanceof Object)
234                         this._pushData(resBody, setmemory);
235                     else setmemory.data = resBody;
236                     var e = new Event('complete_memory_request');
237                     enchant.Core.instance.dispatchEvent(e);
238                     enchant.Core.instance.currentScene.dispatchEvent(e);
239                 }
240             } else {
241                 var id = this._memoryRequests.length;
242                 var request = new enchant.nineleap.memory.MemoryRequest(id, requestType, option, checkError);
243                 this._memoryRequests.push(request);
244                 return id;
245             }
246         },
247 
248         _resend_request: function(requestType, option, checkError) {
249             var id = this.preloadMemory(requestType, option, checkError);
250             if (!enchant.nineleap.memory.LocalStorage.DEBUG_MODE) this._memoryRequests[id]._sendRequest();
251         },
252 
253         check_ajax_running: function(requestType) {
254             if (enchant.nineleap.memory.LocalStorage.DEBUG_MODE) return false;
255             for (var i = 0, l = this._ajaxRequests.length; i < l; i++) {
256                 if (this._ajaxRequests[i].requestType == requestType && this._ajaxRequests[i].running)
257                     return true;
258             }
259             return false;
260         },
261 
262         _setMemoryAssets: function(resBody, requestType, checkError) {
263             var core = enchant.Core.instance;
264             this.memoryQueue--;
265             if (requestType.match(/u\/[0-9a-zA-Z_+]/)) {
266                 this.memory.user[requestType.replace(/u\//, '')] = {};
267                 var setmemory = this.memory.user[requestType.replace(/u\//, '')];
268             } else {
269                 var setmemory = (requestType.match(/user_memory/)) ? this.memory.player :
270                     (requestType.match(/friends_memories/)) ? this.memories.friends :
271                         (requestType.match(/recent_memories/)) ? this.memories.recent :
272                             (requestType.match(/ranking_memories/)) ? this.memories.ranking : null;
273             }
274             if (setmemory == null) return;
275             if (resBody == undefined) {
276             } else if ('code' in resBody) {
277                 if (resBody.code == 401 && this.requireAuth) {
278                     window.location.replace(enchant.nineleap.memory.HttpRequest.SERVER_URL + 'login?after_login=' + window.location.href);
279                     return;
280                 } else if (resBody.code == 401 && !this.requireAuth) {
281                     this.authorized = false;
282                 } else if (resBody.code != 404 && checkError) {
283                     alert(resBody.code + ' error' + '\nリロードしてみてください');
284                     throw new Error(resBody.code + ': ' + resBody.error);
285                     return;
286                 } else if (resBody.code == 403 && checkError) {
287                     alert(resBody.code + ' error' + '\nAPIリクエスト制限オーバーです' + '\n' + requestType);
288                     throw new Error(resBody.code + ': ' + resBody.error);
289                 } else {
290                     if (requestType == "user_memory") {
291                         setmemory.data = {};
292                         setmemory.user = resBody.user;
293                     } else {
294                         setmemory.data = {};
295                     }
296                 }
297                 var e = new Event('error_memory_request');
298                 this.dispatchEvent(e);
299                 this.currentScene.dispatchEvent(e);
300             } else {
301                 if (resBody instanceof Array) {
302                     for (var i = 0, l = resBody.length; i < l; i++) {
303                         setmemory[i] = {};
304                         if (resBody[i] instanceof Object)
305                             this._pushData(resBody[i], setmemory[i]);
306                         else setmemory[i] = resBody[i];
307                     }
308                     setmemory.length = l;
309                 } else if (resBody instanceof Object)
310                     this._pushData(resBody, setmemory);
311                 else setmemory.data = resBody;
312                 var e = new Event('complete_memory_request');
313                 this.dispatchEvent(e);
314                 this.currentScene.dispatchEvent(e);
315             }
316             if (this.memoryQueue == 0 && !this.running) {
317                 this.start();
318             }
319         },
320         _pushData: function(data, obj) {
321             for (var prop in data) {
322                 obj[prop] = data[prop];
323             }
324             if (!enchant.nineleap.memory.LocalStorage.DEBUG_MODE && obj['profile_image_url'] != undefined) {
325                 obj['toSprite'] = function(width, height) {
326                     if (arguments.length < 2) {
327                         var width = 48;
328                         var height = 48;
329                     }
330                     var g = enchant.Core.instance;
331                     var sp = new Sprite(width, height);
332                     sp.image = g.assets[obj['profile_image_url']];
333                     return sp;
334                 };
335                 if (enchant.Core.instance.assets[obj['profile_image_url']] == undefined)
336                     this._memoryAssets.push(obj['profile_image_url']);
337             }
338         },
339         user_preload: function(user, option, checkError) {
340             if (user === undefined) return false;
341             var requestType = 'u/' + user;
342             return enchant.Core.instance.preloadMemory(requestType, option, checkError);
343         },
344         player_preload: function(option, checkError) {
345             var requestType = 'user_memory';
346             return enchant.Core.instance.preloadMemory(requestType, option, checkError);
347         },
348         friends_preload: function(option, checkError) {
349             var requestType = 'friends_memories';
350             return enchant.Core.instance.preloadMemory(requestType, option, checkError);
351         },
352         recent_preload: function(option, checkError) {
353             var requestType = 'recent_memories';
354             return enchant.Core.instance.preloadMemory(requestType, option, checkError);
355         },
356         ranking_preload: function(option, checkError) {
357             var requestType = 'ranking_memories';
358             return enchant.Core.instance.preloadMemory(requestType, option, checkError);
359         },
360         memory_update: function(option, checkError) {
361             var requestType = 'user_memory';
362             var core = enchant.Core.instance;
363             if (core.memory.player.data === undefined ||
364                 core.check_ajax_running(requestType)) return false;
365             if (arguments.length == 1) {
366                 if (typeof arguments[0] == 'boolean') {
367                     checkError = arguments[0];
368                     option = {};
369                 } else {
370                     checkError = true;
371                 }
372             } else if (arguments.length == 0) {
373                 checkError = true;
374                 option = {};
375             }
376             if (enchant.nineleap.memory.LocalStorage.DEBUG_MODE) {
377                 core.ajaxQueue++;
378                 var localstorage = new enchant.nineleap.memory.LocalStorage(LocalStorage.GAME_ID);
379                 localstorage.set_user_memory('mine', core.memory.player.data);
380                 core.ajaxQueue--;
381                 var e = new Event('complete_update');
382                 setTimeout(function() {
383                     core.dispatchEvent(e);
384                     core.currentScene.dispatchEvent(e);
385                 }, 100);
386             } else {
387                 var id = core._ajaxRequests.length;
388                 var data = core.memory.player.data;
389                 var request = new MemoryWrite(id, requestType, function() {
390                     var e = new Event('complete_update');
391                     enchant.Core.instance.dispatchEvent(e);
392                     enchant.Core.instance.currentScene.dispatchEvent(e);
393                 }, checkError, data);
394                 core._ajaxRequests.push(request);
395                 if (core.ajaxQueue + core.memoryQueue < enchant.nineleap.memory.HttpRequest.MAX_REQUEST_SIZE) {
396                     request.send();
397                 } else {
398                     core.addEventListener('complete_xhr_request', function() {
399                         if (core.ajaxQueue + core.memoryQueue < enchant.nineleap.memory.HttpRequest.MAX_REQUEST_SIZE) {
400                             core.removeEventListener('compleate_xhr_request', arguments.callee);
401                             core._ajaxRequests[id].send();
402                         }
403                     });
404                 }
405                 return request;
406             }
407         }
408     });
409 
410 
411     /**
412      * @scope enchant.nineleap.memory.HttpRequest.prototype
413      */
414     enchant.nineleap.memory.HttpRequest = enchant.Class.create(enchant.EventTarget, {
415         /**
416          * HttpRequest クラス
417          * @constructs
418          * @extends enchant.EventTarget
419          */
420         initialize: function() {
421             var xdr, xhr;
422             if (enchant.nineleap.memory.LocalStorage.DEBUG) return;
423             enchant.EventTarget.call(this);
424             this.gameid = enchant.nineleap.memory.LocalStorage.GAME_ID != null ?
425                 enchant.nineleap.memory.LocalStorage.GAME_ID :
426                 location.pathname.match(/^\/games\/(\d+)/)[1];
427             this._running = false;
428             if (window.XMLHttpRequest) {
429                 this.httpRequest = new XMLHttpRequest();
430             } else if (window.XDomainRequest) {
431                 xhr = function() {
432                     this.readyState = 0;
433                     this.responseText = "";
434                     this.status = "";
435                     this.onreadstatechange = undefined;
436 
437                     xdr = new XDomainRequest();
438 
439                     xdr.onprogress = function() {
440                         var f;
441                         this.xhr.readyState = 2;
442                         if (this.xhr && ( f = this.xhr.onreadystatechange )) {
443                             f.apply(this.xhr);
444                         }
445                     };
446 
447                     xdr.onload = function() {
448                         var f;
449                         this.xhr.readyState = 3;
450                         if (this.xhr && ( f = this.xhr.onreadystatechange )) {
451                             f.apply(this.xhr);
452                         }
453                         this.xhr.responseText = xdr.responseText;
454                         this.xhr.readyState = 4;
455                         this.xhr.status = "200";
456                         if (f) {
457                             f.apply(this.xhr);
458                         }
459                     };
460 
461                     xdr.onerror = function() {
462                         var f;
463                         this.xhr.responseText = xdr.responseText;
464                         this.xhr.readyState = 4;
465                         this.xhr.status = "201";
466                         if (this.xhr && ( f = this.xhr.onreadystatechange )) {
467                             f.apply(this.xhr);
468                         }
469                     };
470 
471                     this.open = function(method, url, async) {
472                         return xdr.open(method, url, async);
473                     };
474 
475                     this.send = function(body) {
476                         xdr.send(body);
477                     };
478                     this.setRequestHeader = function(headerName, headerValue) {
479                     };
480                     this.getResponseHeader = function(headerName) {
481                         if (headerName.match(/^Content\-Type$/i)) {
482                             return xdr.contentType;
483                         } else {
484                             return "";
485                         }
486                     };
487                     xdr.xhr = this;
488                     return this;
489                 };
490                 this.httpRequest = new xhr();
491             } else throw new Error('Cannot create XMLHttpRequest object.');
492         },
493         running: {
494             get: function() {
495                 return this._running;
496             }
497         },
498         requestType: {
499             get: function() {
500                 return this._requestType;
501             }
502         }
503     });
504 
505     /**
506      * サーバのURL
507      * @type {String}
508      */
509     enchant.nineleap.memory.HttpRequest.SERVER_URL = 'http://9leap.net/api/';
510 
511     /**
512      * 最大リクエスト数
513      * @type {Number}
514      */
515     enchant.nineleap.memory.HttpRequest.MAX_REQUEST_SIZE = 3;
516 
517     /**
518      * @scope enchant.nineleap.memory.MemoryRequest.prototype
519      */
520     enchant.nineleap.memory.MemoryRequest = enchant.Class.create({
521         /**
522          * メモリAPI に送るリクエスト
523          * @private
524          * @constructs
525          * @param id
526          * @param requestType
527          * @param option
528          * @param checkError
529          */
530         initialize: function(id, requestType, option, checkError) {
531             if (enchant.nineleap.memory.LocalStorage.DEBUG) return;
532             this.id = id;
533             this.checkError = checkError;
534             this.requestType = requestType;
535             var gameid = enchant.nineleap.memory.LocalStorage.GAME_ID != null ?
536                 enchant.nineleap.memory.LocalStorage.GAME_ID :
537                 location.pathname.match(/^\/games\/(\d+)/)[1];
538             var jsonpcallback = '?callback=enchant.Core.instance._memoryRequests[' + id + ']._callback';
539             var src = [HttpRequest.SERVER_URL, 'memory/', gameid, '/', requestType, '.json', jsonpcallback].join('');
540             if (option) {
541                 for (var key in option) {
542                     src += '&' + key + '=' + option[key];
543                 }
544             }
545             this.script = document.createElement('script');
546             this.script.type = 'text/javascript';
547             this.script.src = src;
548         },
549         _callback: function(resBody) {
550             enchant.Core.instance._setMemoryAssets(resBody, this.requestType, this.checkError);
551         },
552         _sendRequest: function() {
553             document.head.appendChild(this.script);
554         }
555     });
556 
557     /**
558      * @scope enchant.nineleap.memory.MemoryWrite.prototype
559      */
560     enchant.nineleap.memory.MemoryWrite = enchant.Class.create(enchant.nineleap.memory.HttpRequest, {
561         /**
562          * メモリAPI に対して書き込みのリクエストを送るためのオブジェクト
563          * @constructs
564          * @param id
565          * @param requestType
566          * @param callback
567          * @param checkError
568          * @param data
569          */
570         initialize: function(id, requestType, callback, checkError, data) {
571             if (enchant.nineleap.memory.LocalStorage.DEBUG) return;
572             enchant.nineleap.memory.HttpRequest.call(this);
573             this.id = id;
574             this.callback = callback;
575             this.checkError = checkError;
576             this._requestType = requestType;
577             this._src = [HttpRequest.SERVER_URL, 'memory/', this.gameid, '/', requestType, '.json'].join('');
578             this._jsonstring = 'json=' + JSON.stringify(data);
579         },
580         send: function() {
581             enchant.Core.instance.ajaxQueue++;
582             this._running = true;
583             this.httpRequest.open('POST', this._src, true);
584             this.httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
585             this.httpRequest.withCredentials = true;
586             var req = this;
587             this.httpRequest.onreadystatechange = function(e) {
588                 switch (req.httpRequest.readyState) {
589                     case 1:
590                         var e = new enchant.Event('loading_xhr_request');
591                         req.dispatchEvent(e);
592                         enchant.Core.instance.dispatchEvent(e);
593                         enchant.Core.instance.currentScene.dispatchEvent(e);
594                         break;
595                     case 2:
596                         var e = new enchant.Event('loaded_xhr_request');
597                         req.dispatchEvent(e);
598                         enchant.Core.instance.dispatchEvent(e);
599                         enchant.Core.instance.currentScene.dispatchEvent(e);
600                         break;
601                     case 3:
602                         var e = new enchant.Event('interactive_xhr_request');
603                         req.dispatchEvent(e);
604                         enchant.Core.instance.dispatchEvent(e);
605                         enchant.Core.instance.currentScene.dispatchEvent(e);
606                         break;
607                     case 4:
608                         enchant.Core.instance.ajaxQueue--;
609                         req._running = false;
610                         var status = req.httpRequest.status;
611                         if (status != 201) {
612                             if (status == 413) {
613                                 if (req.checkError) {
614                                     alert('Too large memory data.');
615                                     throw new Error('Too large memory data.');
616                                 }
617                             } else if (status == 401) {
618                                 if (enchant.Core.instance.requireAuth)
619                                     window.location.replace(HttpRequest.SERVER_URL + 'login?after_login=' + window.location.href);
620                                 else enchant.Core.instance.authorized = false;
621                             } else if (status == 403) {
622                                 if (req.checkError) {
623                                     console.log(req.httpRequest.responseText);
624                                     alert('APIアクセス制限です。');
625                                     throw new Error('Over memory api access limit');
626                                 }
627                             } else {
628                                 if (req.checkError) {
629                                     console.log(req.httpRequest.responseText);
630                                     alert(['status code:', status, ', response:', req.httpRequest.responseText].join(''));
631                                     throw new Error('Cannot write memory data: ' + req._src);
632                                 }
633                             }
634                             var e = new enchant.Event('error_xhr_request');
635                             req.dispatchEvent(e);
636                             enchant.Core.instance.dispatchEvent(e);
637                             enchant.Core.instance.currentScene.dispatchEvent(e);
638                         } else {
639                             (typeof req.callback == 'function') ? req.callback() : Function('x', 'return ' + req.callback);
640                             var e = new enchant.Event('complete_xhr_request');
641                             req.dispatchEvent(e);
642                             enchant.Core.instance.dispatchEvent(e);
643                             enchant.Core.instance.currentScene.dispatchEvent(e);
644                         }
645                         break;
646                 }
647             };
648             this.httpRequest.send(this._jsonstring);
649         }
650     });
651 
652     /**
653      * @scope enchant.nineleap.memory.LocalStorage.prototype
654      */
655     enchant.nineleap.memory.LocalStorage = enchant.Class.create({
656         /**
657          * デバッグ用にローカルストレージを用いるクラス
658          * @constructs
659          * @param requestType
660          * @param callback
661          */
662         initialize: function(requestType, callback) {
663             var game_id = (enchant.nineleap.memory.LocalStorage.GAME_ID == null) ? 0 : enchant.nineleap.memory.LocalStorage.GAME_ID;
664             this._user_memory_key = "game_" + game_id + "_user_";
665         },
666         get_user_memory: function(key) {
667             var value = localStorage.getItem(this._user_memory_key + key);
668             var ret = value ? JSON.parse(value) : null;
669             if (ret == null) return {'data': {}};
670             ret.toSprite = function(width, height) {
671                 if (arguments.length < 2) {
672                     var width = 48;
673                     var height = 48;
674                 }
675                 var g = enchant.Core.instance;
676                 var sp = new Sprite(width, height);
677                 sp.backgroundColor = ret['profile_image_url'];
678                 return sp;
679             }
680             return ret;
681         },
682         set_user_memory: function(key, obj) {
683             if (localStorage.getItem(this._user_memory_key + key) != null)
684                 var color = localStorage.getItem(this._user_memory_key + key).profile_image_url;
685             else var color = null;
686             if (color == null) {
687                 var color_list = ['blue', 'red', 'yellow', 'green', 'orange'];
688                 color = color_list[Math.floor(Math.random() * 5)];
689             }
690             return localStorage.setItem(this._user_memory_key + key,
691                 JSON.stringify({'user': key, 'data': obj, 'updated_at': parseInt((new Date) / 1000), 'profile_image_url': color}));
692         },
693         all_user_memories: {
694             get: function() {
695                 var re = new RegExp(this._user_memory_key);
696                 var list = new Array();
697                 try {
698                     for (var i = 0, l = localStorage.length; i < l; i++) {
699                         var k = localStorage.key(i);
700                         if (k.match(re)) list.push(this.get_user_memory(k.replace(re, "")));
701                     }
702                 } catch (e) {
703                     for (var k in localStorage) {
704                         if (k === 'key') continue;
705                         if (k.match(re)) list.push(this.get_user_memory(k.replace(re, "")));
706                     }
707                 }
708                 return list;
709             }
710         },
711         reset: function() {
712             localStorage.clear();
713         }
714     });
715 
716     /**
717      * Debug mode setting
718      * change true to alter using html5 localStorage api for game memory.
719      */
720     enchant.nineleap.memory.LocalStorage.DEBUG_MODE = false;
721     /**
722      * To debug, setting game ID
723      * Don't change this if you don't upload game to 9leap.net yet.
724      */
725     enchant.nineleap.memory.LocalStorage.GAME_ID = null;
726 
727 })();
728