OSDN Git Service

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