OSDN Git Service

client is version0.4.16, update system.js
[pettanr/pettanr.git] / public / assets / system.js
1 /*
2  * pettanR system.js
3  *   version 0.4.16
4  *   
5  * author:
6  *   itozyun
7  * licence:
8  *   3-clause BSD
9  */
10
11
12 pettanr.log = ( function(){
13         return {
14                 init: function(){}
15         }
16 })();
17
18 pettanr.io = ( function(){
19         
20         return {
21                 init: function(){}
22         }
23 })();
24
25 /*
26  * 画像一覧は
27  *      お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う
28  *  最近アップロードされた画像 > images
29  *  最近使われた画像 > images
30  *  キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う
31  *  風景画像庫 >
32  *  効果画像庫 >
33  *  アイテム画像庫 >
34  *  
35  * 画像一覧を読み込むタイミング
36  */
37 pettanr.file = ( function(){
38         var FILE_TYPE_IS_FOLDER = 1,
39                 numFileType = FILE_TYPE_IS_FOLDER,
40                 FILEDATA_RESITER = [],                  // store all of fileData( json object )
41                 FILEDATA_ACCESS = [],                   // file operations for Kernel only ! hide from Out of pettanr.file
42                 FILE_OBJECT_POOL = [],
43                 EVENT_LISTENER_REGISTER = [],
44                 TREE_ARRAY = [],
45                 TREE_ACCESS_ARRAY = [];
46         
47         var REQUEST_CONTROLER = ( function(){
48                 var REQUEST_TICKET_RESISTER = [],
49                         DATA_TYPE_ARRAY = 'json,xml,html,text'.split( ','),
50                         DATA_IS_JSON = 0,
51                         DATA_IS_XML = 1,
52                         DATA_IS_HTML = 2,
53                         DATA_IS_TEXT = 3,
54                         numError = 0;
55                 
56                 var RequestTicketClass = function( _type, _data, _url, _onLoad, _onError){
57                         this.type = DATA_TYPE_ARRAY[ _type];
58                         this.data = _data;
59                         this.url = _url;
60                         this.onLoad = _onLoad;
61                         this.onError = _onError;
62                         this.state = 0;
63                 };
64                 
65                 function request(){
66                         if( REQUEST_TICKET_RESISTER.length === 0) return;
67                         var _ticket = REQUEST_TICKET_RESISTER.shift();
68                         $.ajax({
69                                 url:            _ticket.url,
70                                 dataType:       _ticket.type,
71                                 success:        function( _data){
72                                         _ticket.onLoad( _ticket.data, _data);
73                                 },
74                                 error:          function(){
75                                         ++numError;
76                                         _ticket.onError( _ticket.data);
77                                 }
78                         });
79                 }
80                 
81                 return {
82                         getNumTask: function(){
83                                 return REQUEST_TICKET_RESISTER.length;
84                         },
85                         getNumError: function(){
86                                 return numError;
87                         },
88                         getJson: function( _data, _url, _onLoad, _onError){
89                                 REQUEST_TICKET_RESISTER.push( new RequestTicketClass( DATA_IS_JSON, _data, _url, _onLoad, _onError));
90                                 request();
91                         }
92                 }
93         })();
94
95
96
97         var FILE_CONTROLER = {
98                 createTree: function( _rootFileData){
99                         var _tree = new TreeClass( _rootFileData);
100                         _tree.init();
101                         TREE_ARRAY.push( _tree);
102                         return _tree;
103                 },
104                 getFileDataAccess: function( UIDorFILEorFILEDATA){
105                         var _uid, _data, _access;
106                         
107                         if( typeof UIDorFILEorFILEDATA === 'number'){
108                                 _data = FILEDATA_RESITER[ UIDorFILEorFILEDATA] || null;
109                         } else
110                         if( UIDorFILEorFILEDATA instanceof FileClass){
111                                 _uid = UIDorFILEorFILEDATA.getUID();
112                                 _data = FILEDATA_RESITER[ _uid] || null;
113                         } else {
114                                 _data = UIDorFILEorFILEDATA || null;
115                         }
116                         
117                         if( _data === null || typeof _data !== 'object') return null;
118                         for( var i=0, l = FILEDATA_ACCESS.length; i<l; ++i){
119                                 _access = FILEDATA_ACCESS[ i];
120                                 if( _access.DATA === _data) return _access;
121                         }
122                         return null;
123                 },              
124                 getFileData: function( UIDorFILEorFILEDATA){
125                         var _access = FILE_CONTROLER.getFileDataAccess( UIDorFILEorFILEDATA);
126                         return _access !== null ? _access.DATA : null;
127                 },
128                 getChildren: function( UIDorFILEorFILEDATA){
129                         var _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA);
130                         return _data !== null ? _data.children || null : null;
131                 },
132                 getDriver: function( _file){
133                         var _data = FILE_CONTROLER.getFileData( _file);
134                         return _data !== null && _data.driver ? _data.driver : FileDriverBase;
135                 },
136                 getUpdateFlag: function( _file, _bit){
137                         var _driver = FILE_CONTROLER.getDriver( _file ),
138                                 _policy;
139                         if( typeof _driver.getUpdatePolicy === 'function'){
140                                 _policy = _driver.getUpdatePolicy( _file );
141                                 
142                         }
143                         if( typeof _policy !== 'number') {
144                                 _policy = FileDriverBase.getUpdatePolicy( _file )
145                         }
146                         return _policy % ( _bit * 2) >= _bit;
147                 },
148                 move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback){
149                         var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID),
150                                 _parentType = _parentData.TYPE,
151                                 _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile),
152                                 _targetType = _targetData.TYPE;
153                 },
154                 replace: function( _uid, _file, _newIndex){
155                         
156                 },
157                 addEventListener: function( FILEorNULL, _eventType, _callback){
158                         var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL;
159                         EVENT_LISTENER_REGISTER.push( new FileEventTicketClass( _uid, _eventType, _callback));
160                 },
161                 removeEventListener: function( FILEorNULL, _eventType, _callback){
162                         var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL,
163                                 _ticket;
164                         for(var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i){
165                                 _ticket = EVENT_LISTENER_REGISTER[i];
166                                 if( _ticket.fileUID === _uid && _ticket.eventType === _eventType && _ticket.callBack === _callback){
167                                         EVENT_LISTENER_REGISTER.splice( i, 1);
168                                         _ticket.destroy();
169                                 }
170                         }
171                 },
172                 getTreeAccess: function(){
173                         
174                 },
175                 fileEventRellay: function( _uid, _event ){
176                         var _fileAccess = FILE_CONTROLER.getFileDataAccess( _uid );
177                         if( _fileAccess === null ) return;
178                         var _treeUID =  _fileAccess.TREE.getUID(),
179                                 _treeAccess = TREE_ACCESS_ARRAY[ _treeUID ],
180                                 _data = _fileAccess.DATA,
181                                 _tree;
182                         if( !_treeAccess ) return;
183                         _treeAccess.dispatchFileEvent( _event );
184                         for( var i=0, l = TREE_ARRAY.length; i<l; ++i){
185                                 if( i !== _treeUID ){
186                                         _tree = TREE_ARRAY[ i ];
187                                         if( FILE_CONTROLER.getFileData( _tree.getCurrentFile() ) === _data ){
188                                                 _treeAccess = TREE_ACCESS_ARRAY[ _tree.getUID() ];
189                                                 _treeAccess && _treeAccess.dispatchFileEvent( _event );
190                                         }
191                                 }
192                         }
193                 }
194         }
195
196         var TreeClass = function( rootFileData ){
197                 var PARENT_FILE_RESITER = [],
198                         ACCESS = {
199                                 dispatchFileEvent:      dispatchFileEvent
200                         },
201                         EVENT_LISTENER_ARRAY = [],
202                         rootFile,
203                         currentFile,
204                         instance;
205                         
206                 TREE_ACCESS_ARRAY.push( ACCESS );
207                 
208                 function dispatchFileEvent( e ){
209                         var _eventType = e.eventType,
210                                 _targetFile = e.targetFile,
211                                 _uid = _targetFile.getUID(),
212                                 _ticket, _type, _callback;
213                         for(var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){
214                                 _ticket = EVENT_LISTENER_REGISTER[ i ];
215                                 _type = _ticket.eventType;
216                                 _callback = _ticket.callBack;
217                                 if( _eventType === _type && _uid === _ticket.fileUID ){
218                                         _callback( _eventType, _targetFile, e.key, e.value );
219                                 } else
220                                 if( _type === pettanr.file.TREE_EVENT.UPDATE && _eventType === pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES ){
221                                         _callback( _eventType, _targetFile );
222                                 }
223                         }
224                 }
225                 
226                 return {
227                         init: function(){
228                                 instance = this;
229                                 currentFile = rootFile = new FileClass( instance, null, rootFileData );
230                                 // rootFile.init();
231                                 currentFile.getSeqentialFiles();
232                                 delete this.init;
233                         },
234                         getUID: function(){
235                                 return pettanr.util.getIndex( TREE_ACCESS_ARRAY, ACCESS );
236                         },
237                         getRootFile : function(){
238                                 return rootFile;
239                         },
240                         getCurrentFile: function(){
241                                 return currentFile;
242                         },
243                         hierarchy: function(){
244                                 return PARENT_FILE_RESITER.length;
245                         },
246                         getParentFileAt: function( _index){
247                                 var l = PARENT_FILE_RESITER.length;
248                                 if( typeof _index !== 'number' || _index < 0 || _index >= l) return null;
249                                 return PARENT_FILE_RESITER[ l -1 -_index];
250                         },
251                         down: function( _index){
252                                 if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return;
253                                 PARENT_FILE_RESITER.unshift( currentFile );
254                                 currentFile = currentFile.getChildFileByIndex( _index );
255                                 currentFile.getSeqentialFiles();
256                                 return currentFile;
257                         },
258                         up: function( _index){
259                                 var l = PARENT_FILE_RESITER.length;
260                                 if( l === 0) return null;
261                                 
262                                 if( currentFile ){
263                                         var _currentFile = currentFile;
264                                         currentFile = null;
265                                         _currentFile.destroy();
266                                 }
267                                 if( typeof _index === 'number'){
268                                         if( _index >= l) return null;
269                                         currentFile = this.getParentFileAt( _index );
270                                         PARENT_FILE_RESITER.splice( 0, l -_index);
271                                 } else {
272                                         currentFile = PARENT_FILE_RESITER.shift();
273                                 }
274                                 currentFile.getSeqentialFiles();
275                                 return currentFile;     
276                         },
277                         addTreeEventListener: function( _eventType, _callback){
278                                 FILE_CONTROLER.addEventListener( null, _eventType, _callback);
279                         },
280                         removeTreeEventListener: function( _eventType, _callback){
281                                 FILE_CONTROLER.removeEventListener( null, _eventType, _callback);
282                         },
283                         destroy: function(){
284                                 FILE_CONTROLER.destroyTree( instance.getUID() );
285                                 // removeEvent
286                                 var _currentFile = currentFile;
287                                 currentFile = rootFile = rootFileData = null;
288                                 _currentFile.destroy();
289                                 while( PARENT_FILE_RESITER.length > 0 ){
290                                         _currentFile = PARENT_FILE_RESITER.shift();
291                                         _currentFile.destroy();
292                                 }
293                                 instance = null;
294                         }
295                 }
296         };
297
298         var FileEventTicketClass = function( UID, _eventType, _callback){
299                 this.fileUID = UID;
300                 this.eventType = _eventType;
301                 this.callBack = _callback;
302                 this.destroy = function(){
303                         this.callBack = _callback = null;
304                 }
305         }
306         
307         var FileEventClass = function( eventType, file, key, value){
308                 this.eventType = eventType;
309                 this.targetFile = file;
310                 this.updatedAttribute = key;
311                 this.updatedValue = value;
312         }
313
314 /*
315  * fileのdataはobjectで保持している。
316  * pettanr.file.の外からファイルをみるときは、FileClassを通して操作する。
317  * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。
318  * treeがdestryされると、fileのイベントリスナーも全て削除される。
319  * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す.
320  */
321         
322         var FileClass = function( tree, parentFile, data ){
323                 var uid = pettanr.util.getIndex( FILEDATA_RESITER, data ),
324                         instance = this;
325                 
326                 if( uid === -1){
327                         uid = FILEDATA_RESITER.length;
328                         FILEDATA_RESITER.push( data );
329                 }
330                 
331                 FILEDATA_ACCESS.push(
332                         {
333                                 TREE:                           tree,
334                                 parentFile:                     parentFile,
335                                 DATA:                           data,
336                                 dispatchFileEvent:      dispatchEvent
337                         }
338                 );
339                 
340                 tree = parentFile = data = null;
341                 
342                 function dispatchEvent( e ){
343                         FILE_CONTROLER.fileEventRellay( uid, e );
344                 }
345                 this.getUID = function(){
346                         return uid;
347                 }
348         };
349         
350         FileClass.prototype = {
351                 isChildFile: function( _FILEorFILEDATA){
352                         return this.getChildFileIndex( _FILEorFILEDATA) !== -1;
353                 },
354                 getSeqentialFiles: function(){
355                         var _driver = FILE_CONTROLER.getDriver( this );
356                         if( _driver !== null && typeof _driver.getSeqentialFiles === 'function'){
357                                 _driver.getSeqentialFiles( this );
358                         }
359                 },
360                 addEventListener: function( _eventType, _callback){
361                         FILE_CONTROLER.addEventListener( this, _eventType, _callback);
362                 },
363                 removeEventListener: function( _eventType, _callback){
364                         FILE_CONTROLER.removeEventListener( this, _eventType, _callback);
365                 },
366                 getChildFileLength: function(){
367                         var children = FILE_CONTROLER.getChildren( this);
368                         return Type.isArray( children ) === true ? children.length : -1;
369                 },
370                 getChildFileIndex: function( _FILEorFILEDATA){
371                         var children = FILE_CONTROLER.getChildren( this);
372                         if( Type.isArray( children.length ) === false ) return -1;
373                         var l = children.length,
374                                 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA);
375                         if( _fileData === null) return -1;
376                         for(var i=0; i<l; ++i){
377                                 if( children[ i] === _fileData) return i;
378                         }
379                         return -1;
380                 },
381                 getName: function(){
382                         var driver = FILE_CONTROLER.getDriver( this );
383                         if( typeof driver.getName === 'function'){
384                                 return driver.getName( this );
385                         }
386                         return FileDriverBase.getName( this);
387                 },
388                 getThumbnail: function(){
389                         var driver = FILE_CONTROLER.getDriver( this);
390                         if( typeof driver.getThumbnail === 'function'){
391                                 return driver.getThumbnail( this);
392                         }
393                         return FileDriverBase.getThumbnail( this);
394                 },
395                 getType: function(){
396                         var _data = FILE_CONTROLER.getFileData( this);
397                         return typeof _data.type === 'number' ? _data.type : pettanr.file.FILE_TYPE.UNKNOWN;
398                 },
399                 getState: function(){
400                         var _data = FILE_CONTROLER.getFileData( this);
401                         return typeof _data.state === 'number' ? _data.state : pettanr.file.FILE_STATE.OK;
402                 },
403                 getSummary: function(){
404                         var driver = FILE_CONTROLER.getDriver( this );
405                         if( typeof driver.getSummary === 'function'){
406                                 return driver.getSummary( this );
407                         }
408                         return FileDriverBase.getSummary( this);
409                 },
410                 isWritable: function(){
411                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.WRITE );
412                 },
413                 isSortable: function(){
414                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.SORT );
415                 },              
416                 isCreatable: function(){
417                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.CREATE );
418                 },
419                 isRenamable: function(){
420                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.RENAME );
421                 },
422                 isDeletable: function(){
423                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.DELETE );
424                 },
425                 read: function(){
426                         // simpleDeepCopy
427                         var driver = FILE_CONTROLER.getDriver( this );
428                         if( typeof driver.read === 'function'){
429                                 return driver.read( this );
430                         }
431                         return FileDriverBase.read( this );
432                 },
433                 write: function( _newName, _newData ){
434                         var driver = FILE_CONTROLER.getDriver( this );
435                         if( typeof driver.write === 'function'){
436                                 return driver.write( this, _newName, _newData );
437                         }
438                         return FileDriverBase.write( this, _newName, _newData );
439                 },
440                 viewerApplicationList: function(){
441                         var driver = FILE_CONTROLER.getDriver( this );
442                         if( typeof driver.viewerApplicationList === 'function'){
443                                 return driver.viewerApplicationList( this );
444                         }
445                         return FileDriverBase.viewerApplicationList( this );
446                 },
447                 editorApplicationList: function(){
448                         var driver = FILE_CONTROLER.getDriver( this );
449                         if( typeof driver.editorApplicationList === 'function'){
450                                 return driver.editorApplicationList( this );
451                         }
452                         return FileDriverBase.viwerApps( this );
453                 },
454                 create: function(){
455                         
456                 },
457                 sort: function(){
458                         
459                 },
460                 onCopy: function(){
461                         
462                 },
463                 onDelete: function(){
464                         
465                 },
466                 getChildFileByIndex: function( _index ){
467                         var _access = FILE_CONTROLER.getFileDataAccess( this ),
468                                 _children = FILE_CONTROLER.getChildren( this );
469                         if( typeof _index !== 'number' || _index < 0 || Type.isArray( _children ) === false || _index >= _children.length) return null;
470                         var _file = new FileClass( _access.TREE, this, _children[ _index ]);
471                         // _file.init();
472                         return _file;
473                 },
474                 move: function( _newFolder, _newIndex, opt_callback ){
475                         var _access = FILE_CONTROLER.getFileDataAccess( this );
476                         _access.TREE.move( _access.parentFile, this.getUID(), _newFolder, _newIndex, opt_callback );
477                 },
478                 replace: function( _newIndex, opt_callback){
479                         var _access = FILE_CONTROLER.getFileDataAccess( this );
480                         _access.TREE.replace( _access.parentFile, this.getUID(), _newIndex, opt_callback);
481                 },
482                 destroy: function(){
483                         var _access = FILE_CONTROLER.getFileDataAccess( this );
484                         var TREE = _access.TREE;
485                         if( TREE.getCurrentFile() === this ) return;
486                         if( TREE.getRootFile() === this ) return;
487                         for( var i=0, l = TREE.hierarchy(); i<l; ++i ){
488                                 if( TREE.getParentFileAt( i ) === this ){
489                                         return;
490                                 }
491                         }
492                         var _index = pettanr.util.getIndex( FILEDATA_ACCESS, _access );
493                         if( _index === -1 || _access === null ) return;
494                         // event の 削除
495                         FILEDATA_ACCESS.splice( _index, 1 );
496                         delete _access.DATA;
497                         delete _access.TREE;
498                         delete _access.parentFile;
499                         delete _access.dispatchFileEvent;
500                 }
501         }
502
503         /*
504          * FileDriverBase
505          */
506         var FileDriverBase = {
507                 getSeqentialFiles: function( _file){
508                 },
509                 getName: function( _file){
510                         var _data = FILE_CONTROLER.getFileData( _file);
511                         return _data.name || 'No Name';
512                 },
513                 getThumbnail: function( _file){
514                         var _data = FILE_CONTROLER.getFileData( _file),
515                                 _type = _data.type,
516                                 _className = '';
517                         if( _type === pettanr.file.FILE_TYPE.FOLDER){
518                                 _className = 'folder';
519                         } else
520                         if( _type === pettanr.file.FILE_TYPE.IMAGE){
521                                 
522                         } else
523                         if( _type === pettanr.file.FILE_TYPE.TEXT){
524                                 
525                         } else
526                         if( _type === pettanr.file.FILE_TYPE.HTML){
527                                 
528                         } else
529                         if( _type === pettanr.file.FILE_TYPE.CSV){
530                                 
531                         } else
532                         if( _type === pettanr.file.FILE_TYPE.JSON){
533                                 
534                         } else
535                         if( _type === pettanr.file.FILE_TYPE.XML){
536                                 
537                         }
538                         return {
539                                 image:          null,
540                                 className:      ' file-type-' + _className
541                         }
542                 },
543                 getSummary: function( _file ){
544                         var _data = FILE_CONTROLER.getFileData( _file ),
545                                 _type = _data.type;
546                         if( _type === pettanr.file.FILE_TYPE.FOLDER){
547                                 return 'folder';
548                         } else
549                         if( _type === pettanr.file.FILE_TYPE.IMAGE){
550                                 return 'image file';
551                         } else
552                         if( _type === pettanr.file.FILE_TYPE.TEXT){
553                                 return 'text file';
554                         } else
555                         if( _type === pettanr.file.FILE_TYPE.HTML){
556                                 return 'html document file';
557                         } else
558                         if( _type === pettanr.file.FILE_TYPE.CSV){
559                                 return 'csv daat file';
560                         } else
561                         if( _type === pettanr.file.FILE_TYPE.JSON){
562                                 return 'json data file';
563                         } else
564                         if( _type === pettanr.file.FILE_TYPE.XML){
565                                 return 'xml data file';
566                         }
567                         return '';
568                 },
569                 getUpdatePolicy: function( _file ){
570                         // debug用 全てのメニューを許可
571                         return pettanr.file.FILE_UPDATE_POLICY.DSRWC;
572                 },
573                 read: function( _file ){
574                         var _data = FILE_CONTROLER.getFileData( _file ),
575                                 _type = _data.type;
576                         return false;
577                 },
578                 write: function( _file, _newName, _newData){
579                         var _data = FILE_CONTROLER.getFileData( _file ),
580                                 _type = _data.type;
581                         return false;
582                 },
583                 viewerApplicationList: function(){
584                         return [];
585                 },
586                 editorApplicationList: function(){
587                         return [];
588                 },
589                 onCreate: function(){
590                         
591                 },
592                 onSort: function(){
593                         
594                 },
595                 onCopy: function(){
596                         
597                 },
598                 onDelete: function(){
599                         
600                 }
601         }
602
603         var ROOT_FILEDATA = {
604                         name:           'system root',
605                         type:           FILE_TYPE_IS_FOLDER,
606                         children:       []
607                 },
608                 SYSTEM_TREE = FILE_CONTROLER.createTree( ROOT_FILEDATA),
609                 ROOT_FILE = SYSTEM_TREE.getRootFile();
610         
611         function createFolderUnderRoot( _fileData){
612                 ROOT_FILEDATA.children.push( _fileData);
613                 FILE_CONTROLER.getFileDataAccess( ROOT_FILE)
614                         .dispatchFileEvent( new FileEventClass( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null));
615         }
616         function createFileEvent( _eventType, _file, _key, _value){
617                 return new FileEventClass( _eventType, _file, _key, _value);
618         }
619         function createFileTypeID(){
620                 return ++numFileType;
621         }
622         
623         return {
624                 init: function(){
625                         //REQUEST_CONTROLER.init();
626                         //FILE_CONTROLER.init();
627                         delete pettanr.file.init;
628                 },
629                 registerDriver: function( _driver){
630                         _driver.prototype = FileDriverBase;
631                         /*
632                          * File API
633                          */
634                         return {
635                                 createFolderUnderRoot:  createFolderUnderRoot,
636                                 getFileDataAccess:              FILE_CONTROLER.getFileDataAccess,
637                                 getFileData:                    FILE_CONTROLER.getFileData,
638                                 getJson:                                REQUEST_CONTROLER.getJson,
639                                 createFileEvent:                createFileEvent,
640                                 createFileTypeID:               createFileTypeID
641                         }
642                 },
643                 createTree: function( _rootFile){
644                         return FILE_CONTROLER.createTree( _rootFile);
645                 },
646                 isTreeInstance: function( _tree){
647                         return _tree instanceof TreeClass;
648                 },
649                 isFileInstance: function( _file){
650                         return _file instanceof FileClass;
651                 },
652                 FILE_TYPE: {
653                         UNKNOWN:        0,
654                         FOLDER:         FILE_TYPE_IS_FOLDER,
655                         IMAGE:          createFileTypeID(),
656                         TEXT:           createFileTypeID(),
657                         HTML:           createFileTypeID(),
658                         CSV:            createFileTypeID(),
659                         JSON:           createFileTypeID(),
660                         XML:            createFileTypeID()
661                 },
662                 FILE_STATE: {
663                         UNKNOWN:        0,
664                         OK:                     1,
665                         LOADING:        2,
666                         ERROR:          3,
667                         BROKEN:         4
668                 },
669                 FILE_UPDATE_POLICY: {
670                         _____:          parseInt( '00000', 2),
671                         ____C:          parseInt( '00001', 2), // hasCreateMenu
672                         ___W_:          parseInt( '00010', 2), // isWritable
673                         ___WC:          parseInt( '00011', 2), // isWritable
674                         __R__:          parseInt( '00100', 2), // isRenamable
675                         __R_C:          parseInt( '00101', 2), // hasCreateMenu
676                         __RW_:          parseInt( '00110', 2), // isWritable
677                         __RWC:          parseInt( '00111', 2), // isWritable
678                         _S___:          parseInt( '01000', 2), // childrenIsSortable
679                         _S__C:          parseInt( '01001', 2),
680                         _S_W_:          parseInt( '01010', 2),
681                         _S_WC:          parseInt( '01011', 2),
682                         _SR__:          parseInt( '01100', 2),
683                         _SR_C:          parseInt( '01101', 2),
684                         _SRW_:          parseInt( '01110', 2),
685                         _SRWC:          parseInt( '01111', 2),
686                         D____:          parseInt( '10000', 2),
687                         D___C:          parseInt( '10001', 2), // hasCreateMenu
688                         D__W_:          parseInt( '10010', 2), // isWritable
689                         D__WC:          parseInt( '10011', 2), // isWritable
690                         D_R__:          parseInt( '10100', 2), // isRenamable
691                         D_R_C:          parseInt( '10101', 2), // hasCreateMenu
692                         D_RW_:          parseInt( '10110', 2), // isWritable
693                         D_RWC:          parseInt( '10111', 2), // isWritable
694                         DS___:          parseInt( '11000', 2), // childrenIsSortable
695                         DS__C:          parseInt( '11001', 2),
696                         DS_W_:          parseInt( '11010', 2),
697                         DS_WC:          parseInt( '11011', 2),
698                         DSR__:          parseInt( '11100', 2),
699                         DSR_C:          parseInt( '11101', 2),
700                         DSRW_:          parseInt( '11110', 2),
701                         DSRWC:          parseInt( '11111', 2),
702                         CREATE:         1,
703                         WRAITE:         2,
704                         RENAME:         4,
705                         SORT:           8,
706                         DELETE:         16
707                 },
708                 TREE_EVENT: {
709                         UPDATE:                         'onTreeUpdate'
710                 },
711                 FILE_EVENT: {
712                         UPDATE_ATTRIVUTE:       'onFileUpdate',
713                         GET_SEQENTIAL_FILES:'gotSeqentilFiles'
714                 },
715                 FILE_DATA_PROPERTY_RESERVED: [
716                         'children', 'driver', 'state', 'type'
717                 ]
718         }
719 })();
720
721 pettanr.finder = ( function(){
722         var FINDER_ARRAY = [],
723                 ELM_ORIGIN_FINDER_LOCATION_ITEM = pettanr.util.pullHtmlAsTemplete( 'templete-finder-location-item'),
724                 ELM_ORIGIN_FINDER_ICON = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon'),
725                 ELM_ORIGIN_CONTAINER = pettanr.util.pullHtmlAsTemplete( 'templete-finder-container'),
726                 ICON_HEIGHT = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON).height,
727                 ICON_CLASSNAME = 'finder-icon-thumbnail',
728                 FINDER_ICON_POOL = [],
729                 BREAD_OBJECT_POOL = [];
730         
731         var FinderIconClass = function(){
732                 var elmContainer,
733                         ELM_WRAPPER = ELM_ORIGIN_FINDER_ICON.cloneNode( true),
734                         ELM_THUMBNAIL = pettanr.util.getElementsByClassName( ELM_WRAPPER, ICON_CLASSNAME )[0],
735                         ELM_FILENAME = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename' )[0],
736                         ELM_DESCRIPTION = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-summary' )[0],
737                         ELM_EDITOR_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-editor-apps' )[0],
738                         ELM_VIEWER_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-viewer-apps' )[0],
739                         ELM_ACTION_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-action' )[0],
740                         file, w, index, style, instansce,
741                         onDownCallback, onEditorCallback, onViewerCallback, onActionCallback,
742                         viewerList, editorList;
743                 ELM_WRAPPER.onmouseover = onOver;
744                 function onOver(){
745                         ELM_WRAPPER.style.backgroundColor = '#eee';
746                 }
747                 ELM_WRAPPER.onmouseout = onOut;
748                 function onOut(){
749                         ELM_WRAPPER.style.backgroundColor = '';
750                 }
751                 
752                 ELM_WRAPPER.onclick = onDownClick;
753                 function onDownClick(){
754                         onDownCallback( index );
755                 }
756                 ELM_EDITOR_BUTTON.onclick = onEditorClick;
757                 function onEditorClick(){
758                         onEditorCallback( index );
759                 }
760                 ELM_VIEWER_BUTTON.onclick = onViwerClick;
761                 function onViwerClick(){
762                         onViewerCallback( index );
763                 }
764                 ELM_ACTION_BUTTON.onclick = onActionClick;
765                 function onActionClick(){
766                         onActionCallback( index );
767                 }
768                 function draw(){
769                         var _thumb = file.getThumbnail();
770                         if( _thumb.image ){
771                                 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';
772                                 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');
773                         } else {
774                                 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' + _thumb.className;
775                                 ELM_THUMBNAIL.style.backgroundImage = '';
776                         }
777                         ELM_FILENAME.firstChild.data = file.getName();
778                         ELM_DESCRIPTION.firstChild.data = file.getSummary();
779                         
780                         if( Type.isArray( viewerList ) === true && viewerList.length > 0 ){
781                                 ELM_VIEWER_BUTTON.style.display = '';
782                         } else {
783                                 ELM_VIEWER_BUTTON.style.display = 'none';
784                         };
785                         if( Type.isArray( editorList ) === true && editorList.length > 0 ){
786                                 ELM_EDITOR_BUTTON.style.display = '';
787                         } else {
788                                 ELM_EDITOR_BUTTON.style.display = 'none';
789                         };
790                 }
791                 function resize(){
792                         ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';
793                 }
794                 function onCollect(){
795                         elmContainer.removeChild( ELM_WRAPPER);
796                         elmContainer = null;
797                         FINDER_ICON_POOL.push( instansce);
798                 }
799                 
800                 return {
801                         init: function( _file, _elmContainer, _w, _index, _style, _onDownCallback, _onEditorCallback, _onViewerCallback, _onActionCallback ){
802                                 instansce = this;
803                                 if( elmContainer !== _elmContainer){
804                                         _elmContainer.appendChild( ELM_WRAPPER);
805                                         elmContainer = _elmContainer;
806                                 }
807                                 if( file !== _file){
808                                         file && file.destroy();
809                                         file = _file;
810                                         viewerList = file.viewerApplicationList();
811                                         editorList = file.editorApplicationList();
812                                         draw();
813                                 }
814                                 if( index !== _index){
815                                         index = _index;
816                                         resize();
817                                 }
818                                 onDownCallback = _onDownCallback;
819                                 onEditorCallback = _onEditorCallback;
820                                 onViewerCallback = _onViewerCallback;
821                                 onActionCallback = _onActionCallback;
822                         },
823                         elm: ELM_WRAPPER,
824                         index: function( _index){
825                                 
826                                 return index;
827                         },
828                         style: function( _style){
829                                 
830                                 return style;
831                         },
832                         onResize: function( w ){
833                                 
834                         },
835                         destroy: function(){
836                                 elmContainer.removeChild( ELM_WRAPPER);
837                                 file && file.destroy();
838                                 file = elmContainer = onDownCallback = onEditorCallback = onViewerCallback = onActionCallback = viewerList = editorList = null;
839                                 FINDER_ICON_POOL.push( instansce);
840                         }
841                 }
842         }
843         function updateIconPosition( _style, _w, _index, _elm){
844                 
845         }
846         var BreadcrumbClass = function(){
847                 var elmContainer,
848                         ELM_WRAPPER = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true),
849                         ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a')[0],
850                         file, w, index, instansce,
851                         callback;
852                 ELM_WRAPPER.onclick = onClick;
853                 function draw(){
854                         ELM_FILENAME.className = 'file-icon-' +file.getType();
855                         ELM_FILENAME.innerHTML = file.getName();
856                 }
857                 function resize( index){
858                         ELM_WRAPPER.style.left = (index * 90) +'px';
859                 }
860                 function onClick(){
861                         callback( index);
862                         return false;
863                 }
864
865                 return {
866                         init: function( _file, _elmContainer, _index, _callback ){
867                                 instansce = this;
868                                 if( elmContainer !== _elmContainer){
869                                         _elmContainer.appendChild( ELM_WRAPPER);
870                                         elmContainer = _elmContainer;
871                                 }
872                                 if( file !== _file){
873                                         file = _file;
874                                         draw();
875                                 }
876                                 if( index !== _index){
877                                         index = _index;
878                                         resize( index);
879                                 }
880                                 callback = _callback;
881                         },
882                         elm: ELM_WRAPPER,
883                         index: function( _index){
884                                 
885                                 return index;
886                         },
887                         onResize: function( w){
888                                 
889                         },
890                         destroy: function(){
891                                 elmContainer.removeChild( ELM_WRAPPER);
892                                 file = elmContainer = null;
893                                 BREAD_OBJECT_POOL.push( this );
894                         }
895                 }
896         }
897         
898         var FinderClass = function( ELM_CONTAINER, tree, header, footer ){
899                 var ICON_ARRAY = [],
900                         BREAD_ARRAY = [],
901                         elmContainer = ELM_ORIGIN_CONTAINER.cloneNode( true ),
902                         elmLocation = elmContainer.getElementsByTagName( 'ul' )[0],
903                         nodesDiv = elmContainer.getElementsByTagName( 'div' ),
904                         elmSidebarButton = nodesDiv[1],
905                         elmStyleButton = nodesDiv[2],
906                         elmActionButton = nodesDiv[3],
907                         elmBody = nodesDiv[ nodesDiv.length -1 ],
908                         //tree = pettanr.file.createTree( TREE_TYPE),
909                         headX,
910                         headY,
911                         headH = pettanr.util.getElementSize( nodesDiv[0] ).height,
912                         bodyY,
913                         currentFile = null,
914                         breadW = 90,
915                         size = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON ),
916                         iconW = size.width,
917                         iconH = size.height,
918                         style = 0,
919                         w, h, bodyH;
920                         
921                 tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, draw);
922                 
923                 function draw( _w, _h ){
924                         w = Type.isFinite( _w ) === true ? _w : w;
925                         h = Type.isFinite( _h ) === true ? _h : h;
926                         bodyH = _h - headH;
927                         var     l = tree.hierarchy() +1,
928                                 m = BREAD_ARRAY.length,
929                                 _file, _bread;
930                         for(var i=0; i<l; ++i){
931                                 _file = i !== l-1 ? tree.getParentFileAt( i) : tree.getCurrentFile();
932                                 if( i < m){
933                                         BREAD_ARRAY[ i].init( _file, elmLocation, i, onHeadClick);
934                                 } else {
935                                         BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick ));
936                                 }
937                         }
938                         while( l < BREAD_ARRAY.length){
939                                 BREAD_ARRAY.pop().destroy();
940                         }
941                         
942                         l = _file.getChildFileLength();
943                         m = ICON_ARRAY.length;
944
945                         for( i=0; i<l; ++i){
946                                 if( i < m){
947                                         ICON_ARRAY[ i ].init( _file.getChildFileByIndex( i), elmBody, w, i, style, onDown, onEditor, onViwer, onAction );
948                                 } else {
949                                         ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i), elmBody, _w, i, style, onDown, onEditor, onViwer, onAction ));
950                                 }
951                         }
952                         if( _file.getState() === pettanr.file.FILE_STATE.LOADING ){
953                                 elmBody.className = 'finder-body loading';
954                         } else {
955                                 elmBody.className = 'finder-body';
956                         }
957                         elmBody.style.height = bodyH + 'px';
958                         
959                         while( l < ICON_ARRAY.length){
960                                 ICON_ARRAY.pop().destroy();
961                         }
962                 }
963                 
964                 function onHeadClick( i){
965                         var l = BREAD_ARRAY.length -1;
966                         if( i < l){
967                                 var _file = tree.getParentFileAt( i);
968                                 if( _file !== null){
969                                         tree.up( i);
970                                         draw( w, h );
971                                 }
972                         }
973                 }
974                 function onDown( i ){
975                         if( i < ICON_ARRAY.length ){
976                                 var _file = tree.getCurrentFile().getChildFileByIndex( i );
977                                 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === pettanr.file.FILE_TYPE.FOLDER)){
978                                         tree.down( i );
979                                         draw( w, h );
980                                 }
981                         }
982                 }
983                 function onEditor( i ){
984                         if( i < ICON_ARRAY.length ){
985                                 var _file = tree.getCurrentFile().getChildFileByIndex( i );
986                         }
987                 }
988                 function onViwer( i ){
989                         if( i < ICON_ARRAY.length ){
990                                 var _file = tree.getCurrentFile().getChildFileByIndex( i );
991                         }
992                 }
993                 function onAction( i ){
994                         if( i < ICON_ARRAY.length ){
995                                 var _file = tree.getCurrentFile().getChildFileByIndex( i );
996
997                         }
998                 }
999                 
1000                 this.init = function(){
1001                         ELM_CONTAINER.appendChild( elmContainer);
1002                         //$( elmLocation).click( onHeadClick);
1003                         //$( elmContainer).click( onBodyClick);
1004                         var position = pettanr.util.getAbsolutePosition( elmLocation);
1005                         headX = position.x;
1006                         headY = position.y;
1007                         bodyY = pettanr.util.getAbsolutePosition( elmBody).y;
1008                         delete this.init;
1009                 }
1010                 this.onOpen = function( _w, _h, _option ){
1011                         this.init !== undefined && this.init();
1012                         draw( _w, _h );
1013                 }
1014                 this.onClose = function(){
1015                         return true;
1016                 }
1017                 this.onPaneResize = function( _w, _h){
1018                         w = _w;
1019                         h = _h;
1020                         elmBody.style.height = ( _h - headH ) + 'px';
1021                         
1022                         for(var i=0, l=ICON_ARRAY.length; i<l; ++i){
1023                                 ICON_ARRAY[ i].onResize( _w );
1024                         }
1025                 }
1026                 this.MIN_WIDTH = 240;
1027                 this.MIN_HEIGHT = 240;
1028         }
1029         
1030         pettanr.view.registerAsBasicPane( FinderClass );
1031         
1032         function getFinderIcon( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction){
1033                 var _icon;
1034                 if( FINDER_ICON_POOL.length > 0){
1035                         _icon = FINDER_ICON_POOL.shift();
1036                 } else {
1037                         _icon = new FinderIconClass();
1038                 }
1039                 _icon.init( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction );
1040                 return _icon;
1041         }
1042         
1043         function getBreadcrumb( _file, _elmContainer, index, callback){
1044                 var _bread;
1045                 if( BREAD_OBJECT_POOL.length > 0){
1046                         _bread = BREAD_OBJECT_POOL.shift();
1047                 } else {
1048                         _bread = new BreadcrumbClass();
1049                 }
1050                 _bread.init( _file, _elmContainer, index, callback);
1051                 return _bread;
1052         }
1053
1054         return {
1055                 init: function(){
1056                         
1057                 },
1058                 createFinder: function( _elmTarget, _tree, _header, _footer ){
1059                         var _finder = new FinderClass( _elmTarget, _tree, _header, _footer );
1060                         FINDER_ARRAY.push( _finder);
1061                         return _finder;
1062                 },
1063                 registerFinderHead: function(){
1064                         
1065                 },
1066                 registerFinderPane: function( _finderPane){
1067                         
1068                 },
1069                 isFinderInstance: function( _finder){
1070                         return _finder instanceof FinderClass;
1071                 },
1072                 isFinderPaneInstance: function(){
1073                         
1074                 },
1075                 isFinderHeadInstance: function(){
1076                 }
1077         }
1078 })();
1079
1080
1081 pettanr.driver = ( function(){
1082         var MyAuthorID = 'current_author' in window ? current_author.id : ( pettanr.DEBUG ? 1 : -1 ),
1083                 MyArtistID = 'current_artist' in window ? current_artist.id : ( pettanr.DEBUG ? 1 : -1 ),
1084                 Driver = {
1085                         getSeqentialFiles: function( _file){
1086                                 var _data = FileAPI.getFileData( _file),
1087                                         _json = _data !== null ? _data.json : null;
1088                                 if( _json === true && _data.type === pettanr.driver.FILE_TYPE.COMIC ){
1089                                         _json = [ pettanr.CONST.PETTANR_ROOT_PATH, 'comics\/', _data.id, '.json\/play\/' ].join( '' );
1090                                 }
1091                                 if( typeof _json === 'string'){
1092                                         FileAPI.getJson( _file, _json, onLoadJson, onErrorJson);
1093                                         _data.state = pettanr.file.FILE_STATE.LOADING;
1094                                         _data.json = null;
1095                                         return;
1096                                 }
1097                         },
1098                         getName: function( _file){
1099                                 var _data = FileAPI.getFileData( _file),
1100                                         _type = _data !== null ? _data.type : null;
1101                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
1102                                         return [ _data.id, _data.ext ].join( '.');
1103                                 } else
1104                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1105                                         return [ _data.t, ':', _data.comic.title ].join( '');
1106                                 } else
1107                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1108                                         return _data.title;
1109                                 } else
1110                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
1111                                         return [ _data.id , ':', _data.name, '画伯' ].join( '');
1112                                 } else
1113                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR ){
1114                                         return [ _data.id , ':', _data.name, '先生' ].join( '');
1115                                 }
1116                                 return _data.name;
1117                         },
1118                         getThumbnail: function( _file){
1119                                 var _data = FileAPI.getFileData( _file),
1120                                         _type = _data !== null ? _data.type : null;
1121                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1122                                         return { image: [ pettanr.CONST.RESOURCE_PICTURE_PATH, 'thumbnail/', _data.id, '.', _data.ext ].join( '')};
1123                                 }
1124                                 if( _data === FILE_DATA_COMICS_ROOT){
1125                                         return { className: 'file-type-cabinet'};
1126                                 }
1127                                 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1128                                         return { className: 'file-type-comic'};
1129                                 }
1130                                 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1131                                         return { className: 'file-type-panel'};
1132                                 }
1133                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1134                                         return { className: 'file-type-author'};
1135                                 }
1136                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1137                                         return { className: 'file-type-artist'};
1138                                 }
1139                                 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1140                                         return { className: 'file-type-folder'};
1141                                 }
1142                                 return { className: 'file-type-broken'};
1143                         },
1144                         getSummary: function( _file ){
1145                                 var _data = FileAPI.getFileData( _file),
1146                                         _type = _data !== null ? _data.type : null;
1147                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1148                                         return [ _data.width, 'x', _data.height, ', filesize:', _data.filesize, ', lisence:', _data.license ].join( '' );
1149                                 }
1150                                 if( _data === FILE_DATA_COMICS_ROOT){
1151                                         return 'cabinet file';
1152                                 }
1153                                 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1154                                         return 'comic file';
1155                                 }
1156                                 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1157                                         return [ _data.width, 'x', _data.height ].join( '' );
1158                                 }
1159                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1160                                         return 'author file';
1161                                 }
1162                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1163                                         return [ 'Email:', _data.email || 'empty' , ', HP:', _data.homepage_url || 'empty' ].join( '' );
1164                                 }
1165                                 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1166                                         return 'pettanR folder';
1167                                 }
1168                                 return 'pettanR unknown file';
1169                         },
1170                         viewerApplicationList: function( _file ){
1171                                 var _data = FileAPI.getFileData( _file ),
1172                                         _type = _data !== null ? _data.type : null;
1173                                 return [];
1174                         },
1175                         editorApplicationList: function( _file ){
1176                                 var _data = FileAPI.getFileData( _file ),
1177                                         _type = _data !== null ? _data.type : null;
1178                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1179                                         return [ pettanr.editor ];
1180                                 }
1181                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1182                                         return [ pettanr.editor, pettanr.comicConsole ];
1183                                 }
1184                                 return [];
1185                         }
1186                 },
1187                 FileAPI = pettanr.file.registerDriver( Driver),
1188                 FILE_DATA_SERVICE_ROOT = {
1189                         name:           'PettanR root',
1190                         type:           pettanr.file.FILE_TYPE.FOLDER,
1191                         children:       []
1192                 },
1193                 FILE_DATA_COMICS_ROOT = {
1194                         name:           'Comics',
1195                         type:           pettanr.file.FILE_TYPE.FOLDER,
1196                         children:       [],
1197                         driver:         Driver,
1198                         json:           pettanr.CONST.URL_COMICS_JSON
1199                 },
1200                 FILE_DATA_PANELS_ROOT = {
1201                         name:           'Panels',
1202                         type:           pettanr.file.FILE_TYPE.FOLDER,
1203                         children:       [],
1204                         driver:         Driver,
1205                         json:           pettanr.CONST.URL_PANELS_JSON
1206                 },
1207                 FILE_DATA_PICTURE_ROOT = {
1208                         name:           'Picutures',
1209                         type:           pettanr.file.FILE_TYPE.FOLDER,
1210                         children:       [],
1211                         driver:         Driver,
1212                         json:           pettanr.CONST.URL_RESOURCE_PICTURES_JSON
1213                 },
1214                 FILE_DATA_MY_COMICS_ROOT = {
1215                         name:           'My Comics',
1216                         type:           pettanr.file.FILE_TYPE.FOLDER,
1217                         children:       [],
1218                         driver:         Driver
1219                 },
1220                 FILE_DATA_LATEST_COMICS = {
1221                         name:           'Latest Comics',
1222                         type:           pettanr.file.FILE_TYPE.FOLDER,
1223                         children:       []
1224                 },
1225                 FILE_DATA_MY_PICTURES_ROOT = {
1226                         name:           'My Pictures',
1227                         type:           pettanr.file.FILE_TYPE.FOLDER,
1228                         children:       [],
1229                         driver:         Driver,
1230                         json:           pettanr.CONST.URL_ORIGINAL_PICTURES_JSON
1231                 },
1232                 FILE_DATA_AUTHOR_ROOT = {
1233                         name:           'Authors',
1234                         type:           pettanr.file.FILE_TYPE.FOLDER,
1235                         children:       []
1236                 },
1237                 FILE_DATA_ARTIST_ROOT = {
1238                         name:           'Artists',
1239                         type:           pettanr.file.FILE_TYPE.FOLDER,
1240                         children:       []
1241                 },
1242                 FILE_DATA_LISENCE_ROOT = {
1243                         name:           'Original Lisences',
1244                         type:           pettanr.file.FILE_TYPE.FOLDER,
1245                         children:       []
1246                 },
1247                 FILE_DATA_BALLOON_ROOT = {
1248                         name:           'Balloon templetes',
1249                         type:           pettanr.file.FILE_TYPE.FOLDER,
1250                         children:       []
1251                 },
1252                 AUTHOR_ARRAY = [],
1253                 ARTIST_ARRAY = [],
1254                 PANEL_ARRAY = [],
1255                 COMIC_ARRAY = [],
1256                 RESOURCE_PICTURE_ARRAY = [],
1257                 BALLOON_TEMPLETE_ARRAY = [],
1258                 ORIGINAL_LICENSE_ARRAY = [],
1259                 BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ',');
1260         FILE_DATA_SERVICE_ROOT.children.push( FILE_DATA_COMICS_ROOT, FILE_DATA_PICTURE_ROOT, FILE_DATA_PANELS_ROOT, FILE_DATA_LISENCE_ROOT, FILE_DATA_BALLOON_ROOT);
1261         FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_LATEST_COMICS, FILE_DATA_AUTHOR_ROOT);
1262         FILE_DATA_PICTURE_ROOT.children.push( FILE_DATA_MY_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT);
1263         
1264         FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT);
1265
1266         function onLoadJson( _file, _json ){
1267                 var _access = FileAPI.getFileDataAccess( _file),
1268                         _data = _access !== null ? _access.DATA : null,
1269                         l;
1270                 if( _data === null){
1271                         onErrorJson( _file);
1272                         return;
1273                 }
1274                 _data.state = pettanr.file.FILE_STATE.OK;
1275                 
1276                 if( Type.isArray( _json ) === true ){
1277                         l = _json.length;
1278                         if( l === 0) return;
1279                         for( var i=0; i<l; ++i ){
1280                                 buildFileData( _json[ i], _data);
1281                         }                       
1282                 } else
1283                 if( _json.id ){
1284                         buildFileData( _json, _data );
1285                 }
1286                 _access.dispatchFileEvent( FileAPI.createFileEvent( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, _file, 'children', null));
1287         }
1288         function onErrorJson( _file ){ 
1289                 var _data = FileAPI.getFileData( _file);
1290                 if( _data !== null){
1291                         _data.state = pettanr.file.FILE_STATE.ERROR;
1292                 }
1293         }
1294         function buildFileData( _data, _parent ){
1295                 var _array, i, l;
1296                 // Panel
1297                 if( _parent === FILE_DATA_PANELS_ROOT ){
1298                         _data.type = pettanr.driver.FILE_TYPE.PANEL;
1299                         _array = PANEL_ARRAY;
1300                 } else
1301                 // Comic
1302                 if( _parent === FILE_DATA_COMICS_ROOT ){
1303                         _data.type = pettanr.driver.FILE_TYPE.COMIC;
1304                         _array = COMIC_ARRAY;
1305                 } else
1306                 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC ){
1307                         _array = COMIC_ARRAY;
1308                 } else
1309                 // Lisence
1310                 if( _parent === FILE_DATA_LISENCE_ROOT ){
1311                         _data.type = pettanr.driver.FILE_TYPE.LICENSE;
1312                         _array = ORIGINAL_LICENSE_ARRAY;
1313                 } else
1314                 // Author
1315                 if( _parent === FILE_DATA_AUTHOR_ROOT ){
1316                         _data.type = pettanr.driver.FILE_TYPE.AUTHOR;
1317                         _array = AUTHOR_ARRAY;
1318                 } else
1319                 // Artist
1320                 if( _parent === FILE_DATA_ARTIST_ROOT ){
1321                         _data.type = pettanr.driver.FILE_TYPE.ARTIST;
1322                         _array = ARTIST_ARRAY;
1323                 } else          
1324                 // Picture
1325                 if( _parent === FILE_DATA_PICTURE_ROOT || _parent === FILE_DATA_MY_PICTURES_ROOT ){
1326                         _data.type = pettanr.driver.FILE_TYPE.PICTURE;
1327                         _array = RESOURCE_PICTURE_ARRAY;
1328                         // original_license を含まなければ、license object を削除して ビットデータ で保持
1329                         // original_license なら ファイルを作る buildFileData( _license, FILE_DATA_LISENCE_ROOT)
1330                         var _license = _data.license,
1331                                 _rule,
1332                                 _Math_pow = Math.pow,
1333                                 _bits = 0;
1334                         if( typeof _license === 'object'){
1335                                 for( i=0, l=BASIC_LICENSES.length; i<l; ++i){
1336                                         _rule = _license[ BASIC_LICENSES[ i]]
1337                                         if( typeof _rule === 'number' && _rule === 1 ){
1338                                                 _bits += _Math_pow( 2, i);
1339                                         }
1340                                 }
1341                                 _data.license = _bits;
1342                         }
1343                 } else {
1344                         alert( 'error' );
1345                 }
1346                 
1347                 _data.driver = Driver;
1348                 
1349                 // _array に _data を格納 または 上書き
1350                 if( typeof _data.id === 'number' && _data.id > 0 ){
1351                         var _id = _data.id - 1,
1352                                 __data = _array[ _id ],
1353                                 _reserved = pettanr.file.FILE_DATA_PROPERTY_RESERVED.join( ', ' );
1354                         if( __data ){
1355                                 for( var key in _data){
1356                                         if( _reserved.indexOf( key ) === -1 ){
1357                                                 __data[ key ] = _data[ key ];
1358                                         }
1359                                 }
1360                                 _data = __data; // このタイミングで参照が切れるので注意!!
1361                         } else {
1362                                 _array[ _id ] = _data;
1363                         }
1364                 } else {
1365                         alert( 'error' );
1366                 }
1367
1368                 // Author
1369                 // Artist
1370                 if( _parent === FILE_DATA_AUTHOR_ROOT || _parent === FILE_DATA_ARTIST_ROOT ){
1371                         addChildData( _parent, _data );
1372                 } else
1373                 // Comic + Panels
1374                 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC || _parent === FILE_DATA_COMICS_ROOT ){
1375                         var _panels = _data.panels,
1376                                 _panel;
1377                         if( _panels && Type.isArray( _panels ) === true ){
1378                                 
1379                                 for( i=0, l=_panels.length; i<l; ++i){
1380                                         _panel = buildFileData( _panels[ i ], FILE_DATA_PANELS_ROOT );
1381                                         /*
1382                                          * 間違い! t 順に格納
1383                                          */
1384                                         addChildData( _data, _panel );
1385                                 }
1386                                 delete _data.panels;
1387                         } else {
1388                                 if( _data.json !== null ){
1389                                         _data.json = true;
1390                                 }
1391                                 if( Type.isArray( _data.children ) === false ){
1392                                         _data.children = [];
1393                                 }                               
1394                         }
1395                         var _author = _data.author || getResource( AUTHOR_ARRAY, _data.author_id );
1396                         if( _author ){
1397                                 _data.author = _author = buildFileData( _author, FILE_DATA_AUTHOR_ROOT );
1398                                 addChildData( _author, _data );
1399                                 _author.id === MyAuthorID && addChildData( FILE_DATA_MY_COMICS_ROOT, _data );
1400                         }
1401                         if( _parent === FILE_DATA_COMICS_ROOT ){
1402                                 addChildData( FILE_DATA_LATEST_COMICS, _data);
1403                         }
1404                 } else
1405                 // Panel
1406                 if( _parent === FILE_DATA_PANELS_ROOT ){
1407                         _data.comic = getResource( COMIC_ARRAY, _data.comic_id );
1408                         _data.author = getResource( AUTHOR_ARRAY, _data.author_id );
1409
1410                         // picture data をファイルに取り出し
1411                         if( Type.isArray( _data.panel_elements ) === true ){
1412                                 var _elements,
1413                                         _elm, _rpic;
1414                                 for( i=0, l=_elements.length; i<l; ++i){
1415                                         _elm = _elements[ i];
1416                                         if( _elm.resource_picture ){
1417                                                 _elm.resource_picture = buildFileData( _elm.resource_picture, FILE_DATA_PICTURE_ROOT); // 上記参照切れに備えてここで上書き
1418                                         } else {
1419                                                 _elm.resource_picture = getResource( RESOURCE_PICTURE_ARRAY, _elm.resource_picture_id );
1420                                         }
1421                                 }                               
1422                         }
1423                 } else
1424                 // Picture
1425                 if( _data.type == pettanr.driver.FILE_TYPE.PICTURE ){
1426                         var _artist = _data.artist || getResource( ARTIST_ARRAY, _data.artist_id );
1427                         if( _artist){
1428                                 _data.artist = _artist = buildFileData( _artist, FILE_DATA_ARTIST_ROOT );
1429                                 addChildData( _artist, _data );
1430                                 _artist.id === MyArtistID && addChildData( FILE_DATA_MY_PICTURES_ROOT, _data );
1431                         }
1432                 }
1433                 return _data;
1434         }
1435         function addChildData( _parent, _child ){
1436                 if( Type.isArray( _parent.children ) === false){
1437                         _parent.children = [];
1438                 }
1439                 pettanr.util.getIndex( _parent.children, _child ) === -1 && _parent.children.push( _child );
1440         }
1441         function getResource( _array, _id ){
1442                 if( Type.isArray( _array ) === false || Type.isNumber( _id ) === false || _id < 1 ) return null;
1443                 var _data = _array[ _id - 1 ];
1444                 if( !_data ){
1445                         _data = _array[ _id - 1 ] = {};
1446                 }
1447                 return _data;
1448         }
1449
1450         return {
1451                 createComicTree: function(){
1452                         return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT); //FILE_DATA_COMICS_ROOT);
1453                 },
1454                 createPictureTree: function(){
1455                         return pettanr.file.createTree( FILE_DATA_PICTURE_ROOT);
1456                 },
1457                 createServiceTree: function(){
1458                         return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT);
1459                 },
1460                 isPettanrFileInstance: function( _file){
1461                         if( pettanr.file.isPettanFileInstance( _file) === true){
1462                                 var _data = FileAPI.getFileData( _file);
1463                                 return _data !== null && _data.driver === Driver;
1464                         }
1465                         return false;
1466                 },
1467                 FILE_TYPE: {
1468                         COMIC:                          FileAPI.createFileTypeID(),
1469                         PANEL:                          FileAPI.createFileTypeID(),
1470                         PICTURE:                        FileAPI.createFileTypeID(),
1471                         PANEL_PICTURE:          FileAPI.createFileTypeID(),
1472                         BALLOON:                        FileAPI.createFileTypeID(),
1473                         AUTHOR:                         FileAPI.createFileTypeID(),
1474                         ARTIST:                         FileAPI.createFileTypeID(),
1475                         LICENSE:                        FileAPI.createFileTypeID()
1476                 }
1477         }
1478 })();
1479
1480 pettanr.entrance = {
1481         displayName: 'Home',
1482         rootElement: document.getElementById('entrance'),
1483         onOpen: function( _w, _h, _option ){
1484                 var pageHeaderH = pettanr.util.getElementSize( document.getElementById('header') ).height;
1485                 document.getElementById('inner-wrapper').style.height = ( _h - pageHeaderH ) + 'px';
1486         },
1487         onClose: function(){
1488                 document.getElementById('inner-wrapper').style.height = '0px';
1489         },
1490         onWindowResize: function( _w, _h){
1491                 pettanr.entrance.onOpen( _w, _h );
1492         }
1493 }
1494 pettanr.view.registerApplication( pettanr.entrance, true );
1495
1496 pettanr.cabinet = ( function(){
1497         var finder,
1498                 elmContainer = document.getElementById( 'cabinet'),
1499                 option,
1500                 pageHeaderH = pettanr.util.getElementSize( document.getElementById('header') ).height;
1501                 
1502         return {
1503                 displayName: 'Comic list',
1504                 rootElement: elmContainer,
1505                 init: function( _option){
1506                         option = _option;
1507                         delete pettanr.cabinet.init;
1508                 },
1509                 onOpen: function( _w, _h, _option ){
1510                         finder = finder || pettanr.finder.createFinder( elmContainer, pettanr.driver.createComicTree());
1511                         finder.onOpen( _w, _h - pageHeaderH, _option );
1512                         
1513                 },
1514                 onClose: function(){
1515                         finder.onClose();
1516                 },
1517                 onWindowResize: function( _w, _h){
1518                         finder.resize( _w, _h - pageHeaderH);
1519                 }
1520         }
1521 })();
1522 pettanr.view.registerApplication( pettanr.cabinet, true );
1523
1524 pettanr.gallery = ( function(){
1525         var finder,
1526                 elmContainer = document.getElementById( 'gallery' ),
1527                 option,
1528                 pageHeaderH = pettanr.util.getElementSize( document.getElementById('header') ).height;
1529         return {
1530                 displayName: 'Pictures',
1531                 rootElement: elmContainer,
1532                 init: function( _option){
1533                         option = _option;
1534                         delete pettanr.gallery.init;
1535                 },
1536                 onOpen: function( _w, _h, _option ){
1537                         finder = finder || pettanr.finder.createFinder( elmContainer, pettanr.driver.createPictureTree());
1538                         finder.onOpen( _w, _h - pageHeaderH, _option );
1539                 },
1540                 onClose: function(){
1541                         finder.onClose();
1542                 },
1543                 onWindowResize: function( _w, _h){
1544                         finder.resize( _w, _h - pageHeaderH );
1545                 }
1546         }
1547 })();
1548 pettanr.view.registerApplication( pettanr.gallery, true );
1549
1550 pettanr.backyard = {
1551         displayName: 'Settings',
1552         rootElement: document.getElementById( 'backyard' ),
1553         onOpen: function( _w, _h, _option ){
1554         },
1555         onClose: function(){
1556         },
1557         onWindowResize: function( _w, _h){
1558         }
1559 }
1560 pettanr.view.registerApplication( pettanr.backyard, true );
1561
1562 if( pettanr.DEBUG === true){
1563         pettanr.debug = ( function(){
1564                 var elmDl = document.getElementById( 'useragent'),
1565                         elmDt, elmDd,
1566                         data = {
1567                                 pettanR:        pettanr.version,
1568                                 ua:                     navigator.userAgent,
1569                                 platform:       navigator.platform,
1570                                 appVersion:     navigator.appVersion,
1571                                 appCodeName:navigator.appCodeName,
1572                                 appName:        navigator.appName,
1573                                 language:       navigator.browserLanguage || navigator.language,
1574                                 ActiveX:        pettanr.ua.ACTIVEX
1575                         },
1576                         ua = pettanr.ua;
1577                 if( ua.IE){
1578                         //data.ua = 'Internet Explorer';
1579                         data.version = ua.IE;
1580                         if( ua.ieVersion >= 8) data.RenderingVersion = ua.ieRenderingVersion;
1581                         data.browserType = ua.STANDALONE === true ? 'Standalone' : 'bundle';
1582                         if( ua.ieVersion < 9) {
1583                                 data.vml = ua.VML;
1584                         } else {
1585                                 data.svg = ua.SVG;
1586                         }
1587                 }
1588                 data.RenderingMode = ua.isStanderdMode === true ? 'Standerd' : 'Quirks';
1589                 
1590                 for( var key in data){
1591                         elmDt = document.createElement( 'dt');
1592                         elmDt.innerHTML = key;
1593                         elmDd = document.createElement( 'dd');
1594                         elmDd.innerHTML = '' + data[ key];
1595                         if( !data[ key]) elmDd.style.color = 'red';
1596                         elmDl.appendChild( elmDt);
1597                         elmDl.appendChild( elmDd);
1598                 }
1599                 return {
1600                         displayName: 'Debug',
1601                         rootElement: document.getElementById( 'debug' ),
1602                         onOpen: function( _w, _h, _option ){
1603                                 var pageHeaderH = pettanr.util.getElementSize( document.getElementById('header') ).height;
1604                                 document.getElementById('inner-wrapper').style.height = ( _h - pageHeaderH ) + 'px';
1605                         },
1606                         onClose: function(){
1607                                 document.getElementById('inner-wrapper').style.height = '0px';
1608                         },
1609                         onWindowResize: function( _w, _h){
1610                                 pettanr.debug.onOpen( _w, _h );
1611                         }                               
1612                 }
1613         })();
1614         pettanr.view.registerApplication( pettanr.debug, true );                        
1615         
1616 } else {
1617         var _debug = document.getElementById( 'debug');
1618         if( _debug){
1619                 pettanr.util.removeAllChildren( _debug);
1620                 _debug.parentNode.removeChild( _debug);
1621                 _debug = null;
1622         }
1623 }
1624
1625 // i18n
1626 // login
1627 // lib
1628
1629 pettanr.fn( pettanr.view);
1630 pettanr.fn( pettanr.overlay);
1631 pettanr.fn( pettanr.key);
1632 pettanr.fn( pettanr.balloon);
1633
1634 pettanr.fn( pettanr.editor);
1635 pettanr.fn( pettanr.comicConsole);
1636 pettanr.fn( pettanr.uploadConsole);
1637 pettanr.fn( pettanr.panelConsole);
1638 pettanr.fn( pettanr.artistConsole);
1639
1640 pettanr.fn( pettanr.file);
1641 pettanr.fn( pettanr.finder);
1642 pettanr.fn( pettanr.gallery);
1643 pettanr.fn( pettanr.cabinet);
1644
1645 $(window).ready( pettanr.init);