OSDN Git Service

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