OSDN Git Service

client is version0.4.15, update pettanr.finder
[pettanr/pettanr.git] / public / assets / system.js
1 /*
2  * pettanR system.js
3  *   version 0.4.15
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                 fileEventRellay: function( _targetFile, _targetTree, _event){
173                         var _uid = _targetTree.getUID(),
174                                 _access = TREE_ACCESS_ARRAY[ _uid ],
175                                 _data = FILE_CONTROLER.getFileData( _targetFile ),
176                                 _tree;
177                         _access && _access.dispatchFileEvent( _event );
178                         for( var i=0, l = TREE_ARRAY.length; i<l; ++i){
179                                 if( i !== _uid){
180                                         _tree = TREE_ARRAY[ i ];
181                                         if( FILE_CONTROLER.getFileData( _tree.getCurrentFile() ) === _data ){
182                                                 _access = TREE_ACCESS_ARRAY[ _tree.getUID() ];
183                                                 _access && _access.dispatchFileEvent( _event);
184                                         }
185                                 }
186                         }
187                 }
188         }
189
190         var TreeClass = function( ROOTFILE_DATA){
191                 var UID = TREE_ACCESS_ARRAY.length,
192                         PARENT_FILE_RESITER = [],
193                         ACCESS = {
194                                 dispatchFileEvent:      dispatchFileEvent,
195                                 destroy:                        onDestroy
196                         },
197                         EVENT_LISTENER_ARRAY = [],
198                         rootFile,
199                         rootFileData,
200                         currentFile,
201                         currentFileData,
202                         instance;
203                         
204                 TREE_ACCESS_ARRAY.push( ACCESS);
205                 
206                 function onDestroy(){
207                         
208                 }
209                 
210                 function dispatchFileEvent( e){
211                         var _eventType = e.eventType,
212                                 _targetFile = e.targetFile,
213                                 _uid = _targetFile.getUID(),
214                                 _ticket, _type, _callback;
215                         for(var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i){
216                                 _ticket = EVENT_LISTENER_REGISTER[i];
217                                 _type = _ticket.eventType;
218                                 _callback = _ticket.callBack;
219                                 if( _eventType === _type && _uid === _ticket.fileUID){
220                                         _callback( _eventType, _targetFile, e.key, e.value);
221                                 } else
222                                 if( _type === pettanr.file.TREE_EVENT.UPDATE && _eventType === pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES){
223                                         _callback( _eventType, _targetFile);
224                                 }
225                         }
226                 }
227                 
228                 return {
229                         init: function(){
230                                 instance = this;
231                                 currentFile = rootFile = new FileClass( this, null, ROOTFILE_DATA);
232                                 // rootFile.init();
233                                 currentFile.getSeqentialFiles();
234                                 delete this.init;
235                         },
236                         getUID: function(){ return UID},
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                                 if( typeof _index === 'number'){
262                                         if( _index >= l) return null;
263                                         currentFile = this.getParentFileAt( _index);
264                                         PARENT_FILE_RESITER.splice( 0, l -_index);
265                                 } else {
266                                         currentFile = PARENT_FILE_RESITER.shift();
267                                 }
268                                 currentFile.getSeqentialFiles();
269                                 return currentFile;     
270                         },
271                         addTreeEventListener: function( _eventType, _callback){
272                                 FILE_CONTROLER.addEventListener( null, _eventType, _callback);
273                         },
274                         removeTreeEventListener: function( _eventType, _callback){
275                                 FILE_CONTROLER.removeEventListener( null, _eventType, _callback);
276                         },
277                         destroy: function(){
278                                 FILE_CONTROLER.destroyTree( UID);
279                         }
280                 }
281         };
282
283         var FileEventTicketClass = function( UID, _eventType, _callback){
284                 this.fileUID = UID;
285                 this.eventType = _eventType;
286                 this.callBack = _callback;
287                 this.destroy = function(){
288                         this.callBack = _callback = null;
289                 }
290         }
291         
292         var FileEventClass = function( eventType, file, key, value){
293                 this.eventType = eventType;
294                 this.targetFile = file;
295                 this.updatedAttribute = key;
296                 this.updatedValue = value;
297         }
298
299 /*
300  * fileのdataはobjectで保持している。
301  * pettanr.file.の外からファイルをみるときは、FileClassを通して操作する。
302  * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。
303  * treeがdestryされると、fileのイベントリスナーも全て削除される。
304  * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す.
305  */
306         
307         var FileClass = function( TREE, parentFile, data){
308                 var uid = pettanr.util.getIndex( FILEDATA_RESITER, data ),
309                         instance = this;
310                 
311                 if( uid === -1){
312                         uid = FILEDATA_RESITER.length;
313                         FILEDATA_RESITER.push( data );
314                 }
315                 
316                 FILEDATA_ACCESS.push(
317                         {
318                                 DATA:                           data,
319                                 updateParent:           updateParent,
320                                 dispatchFileEvent:      dispatchEvent
321                         }
322                 );
323
324                 function updateParent( _parent){
325                         parentFile = _parent;
326                 }
327                 function dispatchEvent( e){
328                         FILE_CONTROLER.fileEventRellay( instance, TREE, e);
329                 }
330                 
331                 /* grobal Methods */
332
333                 this.getUID = function(){
334                         return uid;
335                 }
336                 /*
337                  * ファイル構造は TRON のような ハイパーリンク方式 だが、文脈上の 親ファイルが存在する.その親ファイルを使う操作は.prototype に置く事ができない.
338                  * 同様に TREE を使う操作も .prototype に置く事ができない.
339                  */
340                 this.getChildFileByIndex = function( _index){
341                         var _children = FILE_CONTROLER.getChildren( instance );
342                         if( typeof _index !== 'number' || _index < 0 || typeof _children.length !== 'number' || _index >= _children.length) return null;
343                         var _file = new FileClass( TREE, this, _children[ _index]);
344                         // _file.init();
345                         return _file;
346                 }
347                 this.move = function( _newFolder, _newIndex, opt_callback){
348                         TREE.move( parentFile, UID, _newFolder, _newIndex, opt_callback);
349                 }
350                 this.replace = function( _newIndex, opt_callback){
351                         TREE.replace( parentFile, UID, _newIndex, opt_callback);
352                 }
353                 this.destroy = function(){
354                         var _access = FILE_CONTROLER.getFileDataAccess( instance );
355                                 _index = getChildIndex( FILEDATA_ACCESS, _access );
356                         if( _index === -1 || _access === null) return;
357                         FILEDATA_ACCESS.splice( _index, 1);
358                         TREE = parentFile = data = null;
359                         delete _access.DATA;
360                         delete _access.updateParent;
361                         delete _access.dispatchFileEvent;
362                 }
363         };
364         
365         FileClass.prototype = {
366                 isChildFile: function( _FILEorFILEDATA){
367                         return this.getChildFileIndex( _FILEorFILEDATA) !== -1;
368                 },
369                 getSeqentialFiles: function(){
370                         var _driver = FILE_CONTROLER.getDriver( this );
371                         if( _driver !== null && typeof _driver.getSeqentialFiles === 'function'){
372                                 _driver.getSeqentialFiles( this );
373                         }
374                 },
375                 addEventListener: function( _eventType, _callback){
376                         FILE_CONTROLER.addEventListener( this, _eventType, _callback);
377                 },
378                 removeEventListener: function( _eventType, _callback){
379                         FILE_CONTROLER.removeEventListener( this, _eventType, _callback);
380                 },
381                 getChildFileLength: function(){
382                         var children = FILE_CONTROLER.getChildren( this);
383                         return Type.isArray( children ) === true ? children.length : -1;
384                 },
385                 getChildFileIndex: function( _FILEorFILEDATA){
386                         var children = FILE_CONTROLER.getChildren( this);
387                         if( Type.isArray( children.length ) === false ) return -1;
388                         var l = children.length,
389                                 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA);
390                         if( _fileData === null) return -1;
391                         for(var i=0; i<l; ++i){
392                                 if( children[ i] === _fileData) return i;
393                         }
394                         return -1;
395                 },
396                 getName: function(){
397                         var driver = FILE_CONTROLER.getDriver( this );
398                         if( typeof driver.getName === 'function'){
399                                 return driver.getName( this );
400                         }
401                         return FileDriverBase.getName( this);
402                 },
403                 getThumbnail: function(){
404                         var driver = FILE_CONTROLER.getDriver( this);
405                         if( typeof driver.getThumbnail === 'function'){
406                                 return driver.getThumbnail( this);
407                         }
408                         return FileDriverBase.getThumbnail( this);
409                 },
410                 getType: function(){
411                         var _data = FILE_CONTROLER.getFileData( this);
412                         return typeof _data.type === 'number' ? _data.type : pettanr.file.FILE_TYPE.UNKNOWN;
413                 },
414                 getState: function(){
415                         var _data = FILE_CONTROLER.getFileData( this);
416                         return typeof _data.state === 'number' ? _data.state : pettanr.file.FILE_STATE.OK;
417                 },
418                 getSummary: function(){
419                         var driver = FILE_CONTROLER.getDriver( this );
420                         if( typeof driver.getSummary === 'function'){
421                                 return driver.getSummary( this );
422                         }
423                         return FileDriverBase.getSummary( this);
424                 },
425                 isWritable: function(){
426                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.WRITE);
427                 },
428                 isSortable: function(){
429                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.SORT);
430                 },              
431                 isCreatable: function(){
432                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.CREATE);
433                 },
434                 isRenamable: function(){
435                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.RENAME);
436                 },
437                 read: function(){
438                         // simpleDeepCopy
439                         return false;
440                 },
441                 write: function( _newName, _newData){
442                         return false;
443                 },
444                 viwerApplicationList: function(){
445                         var driver = FILE_CONTROLER.getDriver( this );
446                         if( typeof driver.viwerApplicationList === 'function'){
447                                 return driver.viwerApplicationList( this );
448                         }
449                         return FileDriverBase.viwerApplicationList( this );
450                 },
451                 editorApplicationList: function(){
452                         var driver = FILE_CONTROLER.editorApplicationList( this );
453                         if( typeof driver.editorApplicationList === 'function'){
454                                 return driver.editorApplicationList( this );
455                         }
456                         return FileDriverBase.viwerApps( this );
457                 },
458                 create: function(){
459                         
460                 },
461                 sort: function(){
462                         
463                 },
464                 onCopy: function(){
465                         
466                 },
467                 onDelete: function(){
468                         
469                 }
470         }
471
472         /*
473          * FileDriverBase
474          */
475         var FileDriverBase = {
476                 getSeqentialFiles: function( _file){
477                 },
478                 getName: function( _file){
479                         var _data = FILE_CONTROLER.getFileData( _file);
480                         return _data.name || 'No Name';
481                 },
482                 getThumbnail: function( _file){
483                         var _data = FILE_CONTROLER.getFileData( _file),
484                                 _type = _data.type,
485                                 _className = '';
486                         if( _type === pettanr.file.FILE_TYPE.FOLDER){
487                                 _className = 'folder';
488                         } else
489                         if( _type === pettanr.file.FILE_TYPE.IMAGE){
490                                 
491                         } else
492                         if( _type === pettanr.file.FILE_TYPE.TEXT){
493                                 
494                         } else
495                         if( _type === pettanr.file.FILE_TYPE.HTML){
496                                 
497                         } else
498                         if( _type === pettanr.file.FILE_TYPE.CSV){
499                                 
500                         } else
501                         if( _type === pettanr.file.FILE_TYPE.JSON){
502                                 
503                         } else
504                         if( _type === pettanr.file.FILE_TYPE.XML){
505                                 
506                         }
507                         return {
508                                 image:          null,
509                                 className:      ' file-type-' + _className
510                         }
511                 },
512                 getSummary: function( _file ){
513                         var _data = FILE_CONTROLER.getFileData( _file ),
514                                 _type = _data.type;
515                         if( _type === pettanr.file.FILE_TYPE.FOLDER){
516                                 return 'folder';
517                         } else
518                         if( _type === pettanr.file.FILE_TYPE.IMAGE){
519                                 return 'image file';
520                         } else
521                         if( _type === pettanr.file.FILE_TYPE.TEXT){
522                                 return 'text file';
523                         } else
524                         if( _type === pettanr.file.FILE_TYPE.HTML){
525                                 return 'html document file';
526                         } else
527                         if( _type === pettanr.file.FILE_TYPE.CSV){
528                                 return 'csv daat file';
529                         } else
530                         if( _type === pettanr.file.FILE_TYPE.JSON){
531                                 return 'json data file';
532                         } else
533                         if( _type === pettanr.file.FILE_TYPE.XML){
534                                 return 'xml data file';
535                         }
536                         return '';
537                 },
538                 getUpdatePolicy: function( _file){
539                         // debug用 全てのメニューを許可
540                         return pettanr.file.FILE_UPDATE_POLICY.SRWC;
541                 },
542                 read: function(){
543                         return false;
544                 },
545                 write: function( _newName, _newData){
546                         return false;
547                 },
548                 viwerApplicationList: function(){
549                         return [];
550                 },
551                 editorApplicationList: function(){
552                         return [];
553                 },
554                 onCreate: function(){
555                         
556                 },
557                 onSort: function(){
558                         
559                 },
560                 onCopy: function(){
561                         
562                 },
563                 onDelete: function(){
564                         
565                 }
566         }
567
568         var ROOT_FILEDATA = {
569                         name:           'system root',
570                         type:           FILE_TYPE_IS_FOLDER,
571                         children:       []
572                 },
573                 SYSTEM_TREE = FILE_CONTROLER.createTree( ROOT_FILEDATA),
574                 ROOT_FILE = SYSTEM_TREE.getRootFile();
575         
576         function createFolderUnderRoot( _fileData){
577                 ROOT_FILEDATA.children.push( _fileData);
578                 FILE_CONTROLER.getFileDataAccess( ROOT_FILE)
579                         .dispatchFileEvent( new FileEventClass( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null));
580         }
581         function createFileEvent( _eventType, _file, _key, _value){
582                 return new FileEventClass( _eventType, _file, _key, _value);
583         }
584         function createFileTypeID(){
585                 return ++numFileType;
586         }
587         
588         return {
589                 init: function(){
590                         //REQUEST_CONTROLER.init();
591                         //FILE_CONTROLER.init();
592                         delete pettanr.file.init;
593                 },
594                 registerDriver: function( _driver){
595                         _driver.prototype = FileDriverBase;
596                         /*
597                          * File API
598                          */
599                         return {
600                                 createFolderUnderRoot:  createFolderUnderRoot,
601                                 getFileDataAccess:              FILE_CONTROLER.getFileDataAccess,
602                                 getFileData:                    FILE_CONTROLER.getFileData,
603                                 getJson:                                REQUEST_CONTROLER.getJson,
604                                 createFileEvent:                createFileEvent,
605                                 createFileTypeID:               createFileTypeID
606                         }
607                 },
608                 createTree: function( _rootFile){
609                         return FILE_CONTROLER.createTree( _rootFile);
610                 },
611                 isTreeInstance: function( _tree){
612                         return _tree instanceof TreeClass;
613                 },
614                 isFileInstance: function( _file){
615                         return _file instanceof FileClass;
616                 },
617                 FILE_TYPE: {
618                         UNKNOWN:        0,
619                         FOLDER:         FILE_TYPE_IS_FOLDER,
620                         IMAGE:          createFileTypeID(),
621                         TEXT:           createFileTypeID(),
622                         HTML:           createFileTypeID(),
623                         CSV:            createFileTypeID(),
624                         JSON:           createFileTypeID(),
625                         XML:            createFileTypeID()
626                 },
627                 FILE_STATE: {
628                         UNKNOWN:        0,
629                         OK:                     1,
630                         LOADING:        2,
631                         ERROR:          3,
632                         BROKEN:         4
633                 },
634                 FILE_UPDATE_POLICY: {
635                         ____:           parseInt( '0000', 2),
636                         ___C:           parseInt( '0001', 2), // hasCreateMenu
637                         __W_:           parseInt( '0010', 2), // isWritable
638                         __WC:           parseInt( '0011', 2), // isWritable
639                         _R__:           parseInt( '0000', 2), // isRenamable
640                         _R_C:           parseInt( '0101', 2), // hasCreateMenu
641                         _RW_:           parseInt( '0110', 2), // isWritable
642                         _RWC:           parseInt( '0111', 2), // isWritable
643                         S___:           parseInt( '1000', 2), // childrenIsSortable
644                         S__C:           parseInt( '1001', 2),
645                         S_W_:           parseInt( '1010', 2),
646                         S_WC:           parseInt( '1011', 2),
647                         SR__:           parseInt( '1000', 2),
648                         SR_C:           parseInt( '1101', 2),
649                         SRW_:           parseInt( '1110', 2),
650                         SRWC:           parseInt( '1111', 2),
651                         CREATE:         1,
652                         WRAITE:         2,
653                         RENAME:         4,
654                         SORT:           8
655                 },
656                 TREE_EVENT: {
657                         UPDATE:                         'onTreeUpdate'
658                 },
659                 FILE_EVENT: {
660                         UPDATE_ATTRIVUTE:       'onFileUpdate',
661                         GET_SEQENTIAL_FILES:'gotSeqentilFiles'
662                 },
663                 FILE_DATA_PROPERTY_RESERVED: [
664                         'children', 'driver', 'state', 'type'
665                 ]
666         }
667 })();
668
669 pettanr.finder = ( function(){
670         var FINDER_ARRAY = [],
671                 ELM_ORIGIN_FINDER_LOCATION_ITEM = pettanr.util.pullHtmlAsTemplete( 'templete-finder-location-item'),
672                 ELM_ORIGIN_FINDER_ICON = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon'),
673                 ELM_ORIGIN_CONTAINER = pettanr.util.pullHtmlAsTemplete( 'templete-finder-container'),
674                 ICON_HEIGHT = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON).height,
675                 ICON_CLASSNAME = 'finder-icon-thumbnail',
676                 FINDER_ICON_POOL = [],
677                 BREAD_OBJECT_POOL = [];
678         
679         var FinderIconClass = function(){
680                 var elmContainer,
681                         ELM_WRAPPER = ELM_ORIGIN_FINDER_ICON.cloneNode( true),
682                         ELM_THUMBNAIL = pettanr.util.getElementsByClassName( ELM_WRAPPER, ICON_CLASSNAME )[0],
683                         ELM_FILENAME = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename' )[0],
684                         ELM_DESCRIPTION = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-summary' )[0],
685                         file, w, index, style, instansce, callback;
686                 
687                 ELM_WRAPPER.onclick = onClick;
688                 function onClick(){
689                         callback( index);
690                 }
691
692                 function draw(){
693                         var _thumb = file.getThumbnail();
694                         if( _thumb.image){
695                                 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';
696                                 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');
697                         } else {
698                                 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' +_thumb.className;
699                                 ELM_THUMBNAIL.style.backgroundImage = '';
700                         }
701                         ELM_FILENAME.innerHTML = file.getName();
702                         ELM_DESCRIPTION.innerHTML = file.getSummary();
703                 }
704                 function resize(){
705                         ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';
706                 }
707                 function onCollect(){
708                         elmContainer.removeChild( ELM_WRAPPER);
709                         elmContainer = null;
710                         FINDER_ICON_POOL.push( instansce);
711                 }
712                 
713                 return {
714                         init: function( _file, _elmContainer, _w, _index, _style, _callback){
715                                 instansce = this;
716                                 if( elmContainer !== _elmContainer){
717                                         _elmContainer.appendChild( ELM_WRAPPER);
718                                         elmContainer = _elmContainer;
719                                 }
720                                 if( file !== _file){
721                                         file = _file;
722                                         draw();
723                                 }
724                                 if( index !== _index){
725                                         index = _index;
726                                         resize();
727                                 }
728                                 callback = _callback;
729                         },
730                         elm: ELM_WRAPPER,
731                         index: function( _index){
732                                 
733                                 return index;
734                         },
735                         style: function( _style){
736                                 
737                                 return style;
738                         },
739                         onResize: function( w){
740                                 
741                         },
742                         destroy: function(){
743                                 elmContainer.removeChild( ELM_WRAPPER);
744                                 file = elmContainer = null;
745                                 FINDER_ICON_POOL.push( instansce);
746                         }
747                 }
748         }
749         function updateIconPosition( _style, _w, _index, _elm){
750                 
751         }
752         var BreadcrumbClass = function(){
753                 var elmContainer,
754                         ELM_WRAPPER = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true),
755                         ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a')[0],
756                         file, w, index, instansce,
757                         callback;
758                 ELM_WRAPPER.onclick = onClick;
759                 function draw(){
760                         ELM_FILENAME.className = 'file-icon-' +file.getType();
761                         ELM_FILENAME.innerHTML = file.getName();
762                 }
763                 function resize( index){
764                         ELM_WRAPPER.style.left = (index * 90) +'px';
765                 }
766                 function onClick(){
767                         callback( index);
768                         return false;
769                 }
770
771                 return {
772                         init: function( _file, _elmContainer, _index, _callback){
773                                 instansce = this;
774                                 if( elmContainer !== _elmContainer){
775                                         _elmContainer.appendChild( ELM_WRAPPER);
776                                         elmContainer = _elmContainer;
777                                 }
778                                 if( file !== _file){
779                                         file = _file;
780                                         draw();
781                                 }
782                                 if( index !== _index){
783                                         index = _index;
784                                         resize( index);
785                                 }
786                                 callback = _callback;
787                         },
788                         elm: ELM_WRAPPER,
789                         index: function( _index){
790                                 
791                                 return index;
792                         },
793                         onResize: function( w){
794                                 
795                         },
796                         destroy: function(){
797                                 elmContainer.removeChild( ELM_WRAPPER);
798                                 file = elmContainer = null;
799                                 BREAD_OBJECT_POOL.push( this);
800                         }
801                 }
802         }
803         
804         var FinderClass = function( ELM_CONTAINER, tree, header, footer ){
805                 var ICON_ARRAY = [],
806                         BREAD_ARRAY = [],
807                         elmContainer = ELM_ORIGIN_CONTAINER.cloneNode( true),
808                         elmLocation = elmContainer.getElementsByTagName( 'ul')[0],
809                         nodesDiv = elmContainer.getElementsByTagName( 'div'),
810                         elmSidebarButton = nodesDiv[1],
811                         elmStyleButton = nodesDiv[2],
812                         elmActionButton = nodesDiv[3],
813                         elmBody = nodesDiv[ nodesDiv.length -1 ],
814                         //tree = pettanr.file.createTree( TREE_TYPE),
815                         headX,
816                         headY,
817                         headH = pettanr.util.getElementSize( nodesDiv[0] ).height,
818                         bodyY,
819                         currentFile = null,
820                         breadW = 90,
821                         size = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON ),
822                         iconW = size.width,
823                         iconH = size.height,
824                         style = 0,
825                         w, h, bodyH;
826                         
827                 tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, draw);
828                 
829                 function draw( _w, _h ){
830                         w = Type.isFinite( _w ) === true ? _w : w;
831                         h = Type.isFinite( _h ) === true ? _h : h;
832                         bodyH = _h - headH;
833                         var     l = tree.hierarchy() +1,
834                                 m = BREAD_ARRAY.length,
835                                 _file, _bread;
836                         for(var i=0; i<l; ++i){
837                                 _file = i !== l-1 ? tree.getParentFileAt( i) : tree.getCurrentFile();
838                                 if( i < m){
839                                         BREAD_ARRAY[ i].init( _file, elmLocation, i, onHeadClick);
840                                 } else {
841                                         BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick));
842                                 }
843                         }
844                         while( l < BREAD_ARRAY.length){
845                                 BREAD_ARRAY.pop().destroy();
846                         }
847                         
848                         l = _file.getChildFileLength();
849                         m = ICON_ARRAY.length;
850
851                         for( i=0; i<l; ++i){
852                                 if( i < m){
853                                         ICON_ARRAY[ i].init( _file.getChildFileByIndex( i), elmBody, w, i, style, onBodyClick);
854                                 } else {
855                                         ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i), elmBody, _w, i, style, onBodyClick));
856                                 }
857                         }
858                         if( _file.getState() === pettanr.file.FILE_STATE.LOADING ){
859                                 elmBody.className = 'finder-body loading';
860                         } else {
861                                 elmBody.className = 'finder-body';
862                         }
863                         elmBody.style.height = bodyH + 'px';
864                         
865                         while( l < ICON_ARRAY.length){
866                                 ICON_ARRAY.pop().destroy();
867                         }
868                 }
869                 
870                 function onHeadClick( i){
871                         var l = BREAD_ARRAY.length -1;
872                         if( i < l){
873                                 var _file = tree.getParentFileAt( i);
874                                 if( _file !== null){
875                                         tree.up( i);
876                                         draw( w, h );
877                                 }
878                         }
879                 }
880                 function onBodyClick( i){
881                         var l = ICON_ARRAY.length;
882                         if( i < l){
883                                 var _file = tree.getCurrentFile().getChildFileByIndex( i);
884                                 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === pettanr.file.FILE_TYPE.FOLDER)){
885                                         tree.down( i);
886                                         draw( w, h );
887                                 }
888                         }
889                 }
890                 
891                 this.init = function(){
892                         ELM_CONTAINER.appendChild( elmContainer);
893                         //$( elmLocation).click( onHeadClick);
894                         //$( elmContainer).click( onBodyClick);
895                         var position = pettanr.util.getAbsolutePosition( elmLocation);
896                         headX = position.x;
897                         headY = position.y;
898                         bodyY = pettanr.util.getAbsolutePosition( elmBody).y;
899                         delete this.init;
900                 }
901                 this.onOpen = function( _w, _h, _option ){
902                         this.init !== undefined && this.init();
903                         draw( _w, _h );
904                 }
905                 this.onClose = function(){
906                         return true;
907                 }
908                 this.onPaneResize = function( _w, _h){
909                         w = _w;
910                         h = _h;
911                         elmBody.style.height = ( _h - headH ) + 'px';
912                         
913                         for(var i=0, l=ICON_ARRAY.length; i<l; ++i){
914                                 ICON_ARRAY[ i].onResize( _w );
915                         }
916                 }
917                 this.MIN_WIDTH = 240;
918                 this.MIN_HEIGHT = 240;
919         }
920         
921         pettanr.view.registerAsBasicPane( FinderClass );
922         
923         function getFinderIcon( _file, _elmContainer, w, index, style, callback){
924                 var _icon;
925                 if( FINDER_ICON_POOL.length > 0){
926                         _icon = FINDER_ICON_POOL.shift();
927                 } else {
928                         _icon = new FinderIconClass();
929                 }
930                 _icon.init( _file, _elmContainer, w, index, style, callback);
931                 return _icon;
932         }
933         
934         function getBreadcrumb( _file, _elmContainer, index, callback){
935                 var _bread;
936                 if( BREAD_OBJECT_POOL.length > 0){
937                         _bread = BREAD_OBJECT_POOL.shift();
938                 } else {
939                         _bread = new BreadcrumbClass();
940                 }
941                 _bread.init( _file, _elmContainer, index, callback);
942                 return _bread;
943         }
944
945         return {
946                 init: function(){
947                         
948                 },
949                 createFinder: function( _elmTarget, _tree, _header, _footer ){
950                         var _finder = new FinderClass( _elmTarget, _tree, _header, _footer );
951                         FINDER_ARRAY.push( _finder);
952                         return _finder;
953                 },
954                 registerFinderHead: function(){
955                         
956                 },
957                 registerFinderPane: function( _finderPane){
958                         
959                 },
960                 isFinderInstance: function( _finder){
961                         return _finder instanceof FinderClass;
962                 },
963                 isFinderPaneInstance: function(){
964                         
965                 },
966                 isFinderHeadInstance: function(){
967                 }
968         }
969 })();
970
971
972 pettanr.driver = ( function(){
973         var MyAuthorID = 'current_author' in window ? current_author.id : ( pettanr.DEBUG ? 1 : -1 ),
974                 MyArtistID = 'current_artist' in window ? current_artist.id : ( pettanr.DEBUG ? 1 : -1 ),
975                 Driver = {
976                         getSeqentialFiles: function( _file){
977                                 var _data = FileAPI.getFileData( _file),
978                                         _json = _data !== null ? _data.json : null;
979                                 if( _json === true && _data.type === pettanr.driver.FILE_TYPE.COMIC ){
980                                         _json = [ pettanr.CONST.PETTANR_ROOT_PATH, 'comics\/', _data.id, '.json\/play\/' ].join( '' );
981                                 }
982                                 if( typeof _json === 'string'){
983                                         FileAPI.getJson( _file, _json, onLoadJson, onErrorJson);
984                                         _data.state = pettanr.file.FILE_STATE.LOADING;
985                                         _data.json = null;
986                                         return;
987                                 }
988                         },
989                         getName: function( _file){
990                                 var _data = FileAPI.getFileData( _file),
991                                         _type = _data !== null ? _data.type : null;
992                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
993                                         return [ _data.id, _data.ext ].join( '.');
994                                 } else
995                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
996                                         return [ _data.t, ':', _data.comic.title ].join( '');
997                                 } else
998                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
999                                         return _data.title;
1000                                 } else
1001                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
1002                                         return [ _data.id , ':', _data.name, '画伯' ].join( '');
1003                                 } else
1004                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR ){
1005                                         return [ _data.id , ':', _data.name, '先生' ].join( '');
1006                                 }
1007                                 return _data.name + _data.type;
1008                         },
1009                         getThumbnail: function( _file){
1010                                 var _data = FileAPI.getFileData( _file),
1011                                         _type = _data !== null ? _data.type : null;
1012                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1013                                         return { image: [ pettanr.CONST.RESOURCE_PICTURE_PATH, 'thumbnail/', _data.id, '.', _data.ext ].join( '')};
1014                                 }
1015                                 if( _data === FILE_DATA_COMICS_ROOT){
1016                                         return { className: 'file-type-cabinet'};
1017                                 }
1018                                 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1019                                         return { className: 'file-type-comic'};
1020                                 }
1021                                 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1022                                         return { className: 'file-type-panel'};
1023                                 }
1024                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1025                                         return { className: 'file-type-author'};
1026                                 }
1027                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1028                                         return { className: 'file-type-artist'};
1029                                 }
1030                                 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1031                                         return { className: 'file-type-folder'};
1032                                 }
1033                                 return { className: 'file-type-broken'};
1034                         },
1035                         getSummary: function( _file ){
1036                                 var _data = FileAPI.getFileData( _file),
1037                                         _type = _data !== null ? _data.type : null;
1038                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1039                                         return [ _data.width, 'x', _data.height, ', filesize:', _data.filesize, ', lisence:', _data.license ].join( '' );
1040                                 }
1041                                 if( _data === FILE_DATA_COMICS_ROOT){
1042                                         return 'cabinet file';
1043                                 }
1044                                 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1045                                         return 'comic file';
1046                                 }
1047                                 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1048                                         return [ _data.width, 'x', _data.height ].join( '' );
1049                                 }
1050                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1051                                         return 'author file';
1052                                 }
1053                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1054                                         return [ 'Email:', _data.email || 'empty' , ', HP:', _data.homepage_url || 'empty' ].join( '' );
1055                                 }
1056                                 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1057                                         return 'pettanR folder';
1058                                 }
1059                                 return 'pettanR unknown file';
1060                         },
1061                         viwerApplicationList: function( _file ){
1062                                 var _data = FileAPI.getFileData( _file ),
1063                                         _type = _data !== null ? _data.type : null;
1064                                 return [];
1065                         },
1066                         editorApplicationList: function( _file ){
1067                                 var _data = FileAPI.getFileData( _file ),
1068                                         _type = _data !== null ? _data.type : null;
1069                                 return [];
1070                         }
1071                 },
1072                 FileAPI = pettanr.file.registerDriver( Driver),
1073                 FILE_DATA_SERVICE_ROOT = {
1074                         name:           'PettanR root',
1075                         type:           pettanr.file.FILE_TYPE.FOLDER,
1076                         children:       []
1077                 },
1078                 FILE_DATA_COMICS_ROOT = {
1079                         name:           'Comics',
1080                         type:           pettanr.file.FILE_TYPE.FOLDER,
1081                         children:       [],
1082                         driver:         Driver,
1083                         json:           pettanr.CONST.URL_COMICS_JSON
1084                 },
1085                 FILE_DATA_PANELS_ROOT = {
1086                         name:           'Panels',
1087                         type:           pettanr.file.FILE_TYPE.FOLDER,
1088                         children:       [],
1089                         driver:         Driver,
1090                         json:           pettanr.CONST.URL_PANELS_JSON
1091                 },
1092                 FILE_DATA_PICTURE_ROOT = {
1093                         name:           'Picutures',
1094                         type:           pettanr.file.FILE_TYPE.FOLDER,
1095                         children:       [],
1096                         driver:         Driver,
1097                         json:           pettanr.CONST.URL_RESOURCE_PICTURES_JSON
1098                 },
1099                 FILE_DATA_MY_COMICS_ROOT = {
1100                         name:           'My Comics',
1101                         type:           pettanr.file.FILE_TYPE.FOLDER,
1102                         children:       [],
1103                         driver:         Driver
1104                 },
1105                 FILE_DATA_LATEST_COMICS = {
1106                         name:           'Latest Comics',
1107                         type:           pettanr.file.FILE_TYPE.FOLDER,
1108                         children:       []
1109                 },
1110                 FILE_DATA_MY_PICTURES_ROOT = {
1111                         name:           'My Pictures',
1112                         type:           pettanr.file.FILE_TYPE.FOLDER,
1113                         children:       [],
1114                         driver:         Driver,
1115                         json:           pettanr.CONST.URL_ORIGINAL_PICTURES_JSON
1116                 },
1117                 FILE_DATA_AUTHOR_ROOT = {
1118                         name:           'Authors',
1119                         type:           pettanr.file.FILE_TYPE.FOLDER,
1120                         children:       []
1121                 },
1122                 FILE_DATA_ARTIST_ROOT = {
1123                         name:           'Artists',
1124                         type:           pettanr.file.FILE_TYPE.FOLDER,
1125                         children:       []
1126                 },
1127                 FILE_DATA_LISENCE_ROOT = {
1128                         name:           'Original Lisences',
1129                         type:           pettanr.file.FILE_TYPE.FOLDER,
1130                         children:       []
1131                 },
1132                 FILE_DATA_BALLOON_ROOT = {
1133                         name:           'Balloon templetes',
1134                         type:           pettanr.file.FILE_TYPE.FOLDER,
1135                         children:       []
1136                 },
1137                 AUTHOR_ARRAY = [],
1138                 ARTIST_ARRAY = [],
1139                 PANEL_ARRAY = [],
1140                 COMIC_ARRAY = [],
1141                 RESOURCE_PICTURE_ARRAY = [],
1142                 BALLOON_TEMPLETE_ARRAY = [],
1143                 ORIGINAL_LICENSE_ARRAY = [],
1144                 BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ',');
1145         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);
1146         FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_LATEST_COMICS, FILE_DATA_AUTHOR_ROOT);
1147         FILE_DATA_PICTURE_ROOT.children.push( FILE_DATA_MY_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT);
1148         
1149         FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT);
1150
1151         function onLoadJson( _file, _json){
1152                 var _access = FileAPI.getFileDataAccess( _file),
1153                         _data = _access !== null ? _access.DATA : null,
1154                         l;
1155                 if( _data === null){
1156                         onErrorJson( _file);
1157                         return;
1158                 }
1159                 _data.state = pettanr.file.FILE_STATE.OK;
1160                 
1161                 if( Type.isArray( _json ) === true ){
1162                         l = _json.length;
1163                         if( l === 0) return;
1164                         for( var i=0; i<l; ++i ){
1165                                 buildFileData( _json[ i], _data);
1166                         }                       
1167                 } else
1168                 if( _json.id ){
1169                         buildFileData( _json, _data );
1170                 }
1171                 _access.dispatchFileEvent( FileAPI.createFileEvent( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, _file, 'children', null));
1172         }
1173         function onErrorJson( _file ){ 
1174                 var _data = FileAPI.getFileData( _file);
1175                 if( _data !== null){
1176                         _data.state = pettanr.file.FILE_STATE.ERROR;
1177                 }
1178         }
1179         function buildFileData( _data, _parent ){
1180                 var _array, i, l;
1181                 // Panel
1182                 if( _parent === FILE_DATA_PANELS_ROOT ){
1183                         _data.type = pettanr.driver.FILE_TYPE.PANEL;
1184                         _array = PANEL_ARRAY;
1185                 } else
1186                 // Comic
1187                 if( _parent === FILE_DATA_COMICS_ROOT ){
1188                         _data.type = pettanr.driver.FILE_TYPE.COMIC;
1189                         _array = COMIC_ARRAY;
1190                 } else
1191                 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC ){
1192                         _array = COMIC_ARRAY;
1193                 } else
1194                 // Lisence
1195                 if( _parent === FILE_DATA_LISENCE_ROOT ){
1196                         _data.type = pettanr.driver.FILE_TYPE.LICENSE;
1197                         _array = ORIGINAL_LICENSE_ARRAY;
1198                 } else
1199                 // Author
1200                 if( _parent === FILE_DATA_AUTHOR_ROOT ){
1201                         _data.type = pettanr.driver.FILE_TYPE.AUTHOR;
1202                         _array = AUTHOR_ARRAY;
1203                 } else
1204                 // Artist
1205                 if( _parent === FILE_DATA_ARTIST_ROOT ){
1206                         _data.type = pettanr.driver.FILE_TYPE.ARTIST;
1207                         _array = ARTIST_ARRAY;
1208                 } else          
1209                 // Picture
1210                 if( _parent === FILE_DATA_PICTURE_ROOT || _parent === FILE_DATA_MY_PICTURES_ROOT ){
1211                         _data.type = pettanr.driver.FILE_TYPE.PICTURE;
1212                         _array = RESOURCE_PICTURE_ARRAY;
1213                         // original_license を含まなければ、license object を削除して ビットデータ で保持
1214                         // original_license なら ファイルを作る buildFileData( _license, FILE_DATA_LISENCE_ROOT)
1215                         var _license = _data.license,
1216                                 _rule,
1217                                 _Math_pow = Math.pow,
1218                                 _bits = 0;
1219                         if( typeof _license === 'object'){
1220                                 for( i=0, l=BASIC_LICENSES.length; i<l; ++i){
1221                                         _rule = _license[ BASIC_LICENSES[ i]]
1222                                         if( typeof _rule === 'number' && _rule === 1 ){
1223                                                 _bits += _Math_pow( 2, i);
1224                                         }
1225                                 }
1226                                 _data.license = _bits;
1227                         }
1228                 } else {
1229                         alert( 'error' );
1230                 }
1231                 
1232                 _data.driver = Driver;
1233                 
1234                 // _array に _data を格納 または 上書き
1235                 if( typeof _data.id === 'number' && _data.id > 0 ){
1236                         var _id = _data.id - 1,
1237                                 __data = _array[ _id ],
1238                                 _reserved = pettanr.file.FILE_DATA_PROPERTY_RESERVED.join( ', ' );
1239                         if( __data ){
1240                                 for( var key in _data){
1241                                         if( _reserved.indexOf( key ) === -1 ){
1242                                                 __data[ key ] = _data[ key ];
1243                                         }
1244                                 }
1245                                 _data = __data; // このタイミングで参照が切れるので注意!!
1246                         } else {
1247                                 _array[ _id ] = _data;
1248                         }
1249                 } else {
1250                         alert( 'error' );
1251                 }
1252
1253                 // Author
1254                 // Artist
1255                 if( _parent === FILE_DATA_AUTHOR_ROOT || _parent === FILE_DATA_ARTIST_ROOT ){
1256                         addChildData( _parent, _data );
1257                 } else
1258                 // Comic + Panels
1259                 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC || _parent === FILE_DATA_COMICS_ROOT ){
1260                         var _panels = _data.panels,
1261                                 _panel;
1262                         if( _panels && Type.isArray( _panels ) === true ){
1263                                 
1264                                 for( i=0, l=_panels.length; i<l; ++i){
1265                                         _panel = buildFileData( _panels[ i ], FILE_DATA_PANELS_ROOT );
1266                                         /*
1267                                          * 間違い! t 順に格納
1268                                          */
1269                                         addChildData( _data, _panel );
1270                                 }
1271                                 delete _data.panels;
1272                         } else {
1273                                 if( _data.json !== null ){
1274                                         _data.json = true;
1275                                 }
1276                                 if( Type.isArray( _data.children ) === false ){
1277                                         _data.children = [];
1278                                 }                               
1279                         }
1280                         var _author = _data.author || getResource( AUTHOR_ARRAY, _data.author_id );
1281                         if( _author ){
1282                                 _data.author = _author = buildFileData( _author, FILE_DATA_AUTHOR_ROOT );
1283                                 addChildData( _author, _data );
1284                                 _author.id === MyAuthorID && addChildData( FILE_DATA_MY_COMICS_ROOT, _data );
1285                         }
1286                         if( _parent === FILE_DATA_COMICS_ROOT ){
1287                                 addChildData( FILE_DATA_LATEST_COMICS, _data);
1288                         }
1289                 } else
1290                 // Panel
1291                 if( _parent === FILE_DATA_PANELS_ROOT ){
1292                         _data.comic = getResource( COMIC_ARRAY, _data.comic_id );
1293                         _data.author = getResource( AUTHOR_ARRAY, _data.author_id );
1294
1295                         // picture data をファイルに取り出し
1296                         if( Type.isArray( _data.panel_elements ) === true ){
1297                                 var _elements,
1298                                         _elm, _rpic;
1299                                 for( i=0, l=_elements.length; i<l; ++i){
1300                                         _elm = _elements[ i];
1301                                         if( _elm.resource_picture ){
1302                                                 _elm.resource_picture = buildFileData( _elm.resource_picture, FILE_DATA_PICTURE_ROOT); // 上記参照切れに備えてここで上書き
1303                                         } else {
1304                                                 _elm.resource_picture = getResource( RESOURCE_PICTURE_ARRAY, _elm.resource_picture_id );
1305                                         }
1306                                 }                               
1307                         }
1308                 } else
1309                 // Picture
1310                 if( _data.type == pettanr.driver.FILE_TYPE.PICTURE ){
1311                         var _artist = _data.artist || getResource( ARTIST_ARRAY, _data.artist_id );
1312                         if( _artist){
1313                                 _data.artist = _artist = buildFileData( _artist, FILE_DATA_ARTIST_ROOT );
1314                                 addChildData( _artist, _data );
1315                                 _artist.id === MyArtistID && addChildData( FILE_DATA_MY_PICTURES_ROOT, _data );
1316                         }
1317                 }
1318                 return _data;
1319         }
1320         function addChildData( _parent, _child ){
1321                 if( Type.isArray( _parent.children ) === false){
1322                         _parent.children = [];
1323                 }
1324                 pettanr.util.getIndex( _parent.children, _child ) === -1 && _parent.children.push( _child );
1325         }
1326         function getResource( _array, _id ){
1327                 if( Type.isArray( _array ) === false || Type.isNumber( _id ) === false || _id < 1 ) return null;
1328                 var _data = _array[ _id - 1 ];
1329                 if( !_data ){
1330                         _data = _array[ _id - 1 ] = {};
1331                 }
1332                 return _data;
1333         }
1334
1335         return {
1336                 createComicTree: function(){
1337                         return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT); //FILE_DATA_COMICS_ROOT);
1338                 },
1339                 createPictureTree: function(){
1340                         return pettanr.file.createTree( FILE_DATA_PICTURE_ROOT);
1341                 },
1342                 createServiceTree: function(){
1343                         return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT);
1344                 },
1345                 isPettanrFileInstance: function( _file){
1346                         if( pettanr.file.isPettanFileInstance( _file) === true){
1347                                 var _data = FileAPI.getFileData( _file);
1348                                 return _data !== null && _data.driver === Driver;
1349                         }
1350                         return false;
1351                 },
1352                 FILE_TYPE: {
1353                         COMIC:                          FileAPI.createFileTypeID(),
1354                         PANEL:                          FileAPI.createFileTypeID(),
1355                         PICTURE:                        FileAPI.createFileTypeID(),
1356                         PANEL_PICTURE:          FileAPI.createFileTypeID(),
1357                         BALLOON:                        FileAPI.createFileTypeID(),
1358                         AUTHOR:                         FileAPI.createFileTypeID(),
1359                         ARTIST:                         FileAPI.createFileTypeID(),
1360                         LICENSE:                        FileAPI.createFileTypeID()
1361                 }
1362         }
1363 })();
1364
1365
1366 pettanr.gallery = ( function(){
1367         var finder,
1368                 elmContainer = document.getElementById( 'gallery'),
1369                 option,
1370                 pageHeaderH = pettanr.util.getElementSize( document.getElementById('header') ).height;
1371         return {
1372                 init: function( _option){
1373                         option = _option;
1374                         delete pettanr.gallery.init;
1375                 },
1376                 firstOpen: function(){
1377                         finder = pettanr.finder.createFinder( elmContainer, pettanr.driver.createPictureTree());
1378                         delete pettanr.gallery.firstOpen;
1379                 },
1380                 onOpen: function( _w, _h, _option ){
1381                         pettanr.gallery.firstOpen !== undefined && pettanr.gallery.firstOpen();
1382                         finder.onOpen( _w, _h - pageHeaderH, _option );
1383                         
1384                 },
1385                 onClose: function(){
1386                         finder.onClose();
1387                 },
1388                 onWindowResize: function( _w, _h){
1389                         finder.resize( _w, _h - pageHeaderH );
1390                 }
1391         }
1392 })();
1393
1394 pettanr.cabinet = ( function(){
1395         var finder,
1396                 elmContainer = document.getElementById( 'cabinet'),
1397                 option,
1398                 pageHeaderH = pettanr.util.getElementSize( document.getElementById('header') ).height;
1399                 
1400         return {
1401                 init: function( _option){
1402                         option = _option;
1403                         delete pettanr.cabinet.init;
1404                 },
1405                 firstOpen: function(){
1406                         finder = pettanr.finder.createFinder( elmContainer, pettanr.driver.createComicTree());
1407                         delete pettanr.cabinet.firstOpen;
1408                 },
1409                 onOpen: function( _w, _h, _option ){
1410                         pettanr.cabinet.firstOpen !== undefined && pettanr.cabinet.firstOpen();
1411                         finder.onOpen( _w, _h - pageHeaderH, _option );
1412                         
1413                 },
1414                 onClose: function(){
1415                         finder.onClose();
1416                 },
1417                 onWindowResize: function( _w, _h){
1418                         finder.resize( _w, _h - pageHeaderH);
1419                 }
1420         }
1421 })();
1422
1423 // i18n
1424 // login
1425 // lib
1426
1427 pettanr.fn( pettanr.view);
1428 pettanr.fn( pettanr.overlay);
1429 pettanr.fn( pettanr.key);
1430 pettanr.fn( pettanr.balloon);
1431
1432 pettanr.fn( pettanr.editor);
1433 pettanr.fn( pettanr.comicConsole);
1434 pettanr.fn( pettanr.uploadConsole);
1435 pettanr.fn( pettanr.panelConsole);
1436 pettanr.fn( pettanr.artistConsole);
1437
1438 pettanr.fn( pettanr.file);
1439 pettanr.fn( pettanr.finder);
1440 pettanr.fn( pettanr.gallery);
1441 pettanr.fn( pettanr.cabinet);
1442
1443 $(window).ready( pettanr.init);