OSDN Git Service

pass test
[pettanr/pettanr.git] / public / assets / system.js
1 /*
2  * pettanR system.js
3  *   version 0.4.36
4  *   
5  * author:
6  *   itozyun
7  * licence:
8  *   3-clause BSD
9  */
10
11 /*
12  * 画像一覧は
13  *      お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う
14  *  最近アップロードされた画像 > images
15  *  最近使われた画像 > images
16  *  キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う
17  *  風景画像庫 >
18  *  効果画像庫 >
19  *  アイテム画像庫 >
20  *  
21  * 画像一覧を読み込むタイミング
22  */
23 pettanr.file = ( function(){
24         var FILE_TYPE_IS_FOLDER = 1,
25                 numFileType = FILE_TYPE_IS_FOLDER,
26                 FILEDATA_RESITER = [],                  // store all of fileData( json object )
27                 FILEDATA_ACCESS = [],                   // file operations for Kernel only ! hide from Out of pettanr.file
28                 FILE_OBJECT_POOL = [],
29                 EVENT_LISTENER_REGISTER = [],
30                 TREE_ARRAY = [],
31                 TREE_ACCESS_ARRAY = [];
32         
33         var REQUEST_CONTROLER = ( function(){
34                 var REQUEST_TICKET_RESISTER = [],
35                         currentTicket = null,
36                         currentData = null,
37                         DATA_TYPE_ARRAY = 'json,xml,html,text'.split( ','),
38                         DATA_IS_JSON = 0,
39                         DATA_IS_XML = 1,
40                         DATA_IS_HTML = 2,
41                         DATA_IS_TEXT = 3,
42                         numError = 0;
43                 
44                 var RequestTicketClass = function( _type, _data, _url, _onLoad, _onError){
45                         this.type = DATA_TYPE_ARRAY[ _type];
46                         this.data = _data;
47                         this.url = _url;
48                         this.onLoad = _onLoad;
49                         this.onError = _onError;
50                         this.state = 0;
51                 };
52                 
53                 function request(){
54                         if( currentTicket !== null ) return;
55                         currentTicket = REQUEST_TICKET_RESISTER.shift();
56                         $.ajax({
57                                 url:            currentTicket.url,
58                                 dataType:       currentTicket.type,
59                                 success:        onSuccess,
60                                 error:          onError
61                         });
62                 }
63                 function onSuccess( _data ){
64                         currentData = _data;
65                         window.setTimeout( asyncSuccess, 0 );
66                 }
67                         function asyncSuccess(){
68                                 currentTicket.onLoad( currentTicket.data, currentData );
69                                 currentTicket = currentData = null;
70                                 REQUEST_TICKET_RESISTER.length !== 0 && window.setTimeout( request, 0 );
71                         }
72                 
73                 function onError(){
74                         ++numError;
75                         window.setTimeout( asyncError, 0 );
76                 }
77                         function asyncError(){
78                                 currentTicket.onError( currentTicket.data );
79                                 currentTicket = null;
80                                 REQUEST_TICKET_RESISTER.length !== 0 && window.setTimeout( request, 0 );
81                         }
82                 return {
83                         getNumTask: function(){
84                                 return REQUEST_TICKET_RESISTER.length;
85                         },
86                         getNumError: function(){
87                                 return numError;
88                         },
89                         getJson: function( _data, _url, _onLoad, _onError ){
90                                 REQUEST_TICKET_RESISTER.push( new RequestTicketClass( DATA_IS_JSON, _data, _url, _onLoad, _onError));
91                                 currentTicket === null && request();
92                         }
93                 }
94         })();
95
96
97
98         var FILE_CONTROLER = {
99                 createTree: function( _rootFileData){
100                         var _tree = new TreeClass( _rootFileData);
101                         _tree.init();
102                         TREE_ARRAY.push( _tree);
103                         return _tree;
104                 },
105                 getFileUID: function( FILEDATAorFILE ){
106                         if( FILEDATAorFILE instanceof FileClass ){
107                                 return FILEDATAorFILE.getUID();
108                         }
109                         
110                         var uid = pettanr.util.getIndex( FILEDATA_RESITER, FILEDATAorFILE );
111                         if( uid === -1){
112                                 uid = FILEDATA_RESITER.length;
113                                 FILEDATA_RESITER.push( FILEDATAorFILE );
114                         }
115                         return uid;
116                 },
117                 getFileDataAccess: function( UIDorFILEorFILEDATA){
118                         var _uid, _data, _access;
119                         
120                         if( typeof UIDorFILEorFILEDATA === 'number'){
121                                 _data = FILEDATA_RESITER[ UIDorFILEorFILEDATA ] || null;
122                         } else
123                         if( UIDorFILEorFILEDATA instanceof FileClass){
124                                 _uid = UIDorFILEorFILEDATA.getUID();
125                                 _data = FILEDATA_RESITER[ _uid ] || null;
126                         } else {
127                                 _data = UIDorFILEorFILEDATA || null;
128                         }
129                         
130                         if( _data === null || typeof _data !== 'object') return null;
131                         for( var i=0, l = FILEDATA_ACCESS.length; i<l; ++i){
132                                 _access = FILEDATA_ACCESS[ i];
133                                 if( _access.DATA === _data) return _access;
134                         }
135                         return null;
136                 },      
137                 getFileData: function( UIDorFILEorFILEDATA){
138                         var _access = FILE_CONTROLER.getFileDataAccess( UIDorFILEorFILEDATA);
139                         return _access !== null ? _access.DATA : null;
140                 },
141                 getChildren: function( UIDorFILEorFILEDATA){
142                         var _data = FILE_CONTROLER.getFileData( UIDorFILEorFILEDATA);
143                         return _data !== null ? _data.children || null : null;
144                 },
145                 getDriver: function( _file){
146                         var _data = FILE_CONTROLER.getFileData( _file);
147                         return _data !== null && _data.driver ? _data.driver : FileDriverBase;
148                 },
149                 getUpdateFlag: function( _file, _bit ){
150                         var _driver = FILE_CONTROLER.getDriver( _file ),
151                                 _policy;
152                         if( typeof _driver.getUpdatePolicy === 'function'){
153                                 _policy = _driver.getUpdatePolicy( _file );
154                                 
155                         }
156                         if( typeof _policy !== 'number') {
157                                 _policy = FileDriverBase.getUpdatePolicy( _file )
158                         }
159                         return _policy % ( _bit * 2) >= _bit;
160                 },
161                 move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback){
162                         var _parentData = FILE_CONTROLER.getFileDataAccess( _prentUID),
163                                 _parentType = _parentData.TYPE,
164                                 _targetData = FILE_CONTROLER.getFileDataAccess( _targetfile),
165                                 _targetType = _targetData.TYPE;
166                 },
167                 replace: function( _uid, _file, _newIndex){
168                         
169                 },
170                 addEventListener: function( FILEorNULL, _eventType, _callback ){
171                         var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL;
172                         EVENT_LISTENER_REGISTER.push( new FileEventTicketClass( _uid, _eventType, _callback));
173                 },
174                 removeEventListener: function( FILEorNULL, _eventType, _callback ){
175                         var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL,
176                                 _ticket;
177                         for(var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){
178                                 _ticket = EVENT_LISTENER_REGISTER[ i ];
179                                 if( _ticket.fileUID === _uid && _ticket.eventType === _eventType && _ticket.callBack === _callback ){
180                                         EVENT_LISTENER_REGISTER.splice( i, 1 );
181                                         _ticket.destroy();
182                                 }
183                         }
184                 },
185                 getTreeAccess: function(){
186                         
187                 },
188                 fileEventRellay: function( _uid, _event ){
189                         var _fileAccess = FILE_CONTROLER.getFileDataAccess( _uid );
190                         if( _fileAccess === null ) return;
191                         var _treeUID =  _fileAccess.TREE.getUID(),
192                                 _treeAccess = TREE_ACCESS_ARRAY[ _treeUID ],
193                                 _data = _fileAccess.DATA,
194                                 _tree;
195                         if( !_treeAccess ) return;
196                         _treeAccess.dispatchFileEvent( _event );
197                         for( var i=0, l = TREE_ARRAY.length; i<l; ++i){
198                                 if( i !== _treeUID ){
199                                         _tree = TREE_ARRAY[ i ];
200                                         if( FILE_CONTROLER.getFileData( _tree.getCurrentFile() ) === _data ){
201                                                 _treeAccess = TREE_ACCESS_ARRAY[ _tree.getUID() ];
202                                                 _treeAccess && _treeAccess.dispatchFileEvent( _event );
203                                         }
204                                 }
205                         }
206                 }
207         }
208         
209         var AsyncEventDispatcher = ( function(){
210                 var STACK_LIST = [];
211                 
212                 function dispatch(){
213                         var _stack = STACK_LIST.shift();
214                         _stack[ 0 ]( _stack[ 1 ], _stack[ 2 ], _stack[ 3 ], _stack[ 4 ] );
215                         
216                         while( _stack.length > 0 ){
217                                 _stack.shift();
218                         }
219                         if( STACK_LIST.length !== 0 ){
220                                 window.setTimeout( dispatch, 0 );
221                         }
222                 }
223                 return {
224                         addEvent: function( _callback, _eventType, _targetFile, _key, _value ){
225                                 if( STACK_LIST.length === 0 ){
226                                         window.setTimeout( dispatch, 0 );
227                                 }
228                                 STACK_LIST.push( [ _callback, _eventType, _targetFile, _key, _value ] );
229                         }
230                 }
231         })();
232         
233         var TreeClass = function( rootFileData ){
234                 var PARENT_FILE_RESITER = [],
235                         ACCESS = {
236                                 dispatchFileEvent:      dispatchFileEvent
237                         },
238                         EVENT_LISTENER_ARRAY = [],
239                         rootFile,
240                         currentFile,
241                         instance;
242                         
243                 TREE_ACCESS_ARRAY.push( ACCESS );
244                 
245                 function dispatchFileEvent( e ){
246                         var _eventType = e.eventType,
247                                 _targetFile = e.targetFile,
248                                 _uid = _targetFile.getUID(),
249                                 _ticket, _type, _callback;
250                         for( var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){
251                                 _ticket = EVENT_LISTENER_REGISTER[ i ];
252                                 _type = _ticket.eventType;
253                                 _callback = _ticket.callBack;
254                                 if( _eventType === _type && _uid === _ticket.fileUID ){
255                                         AsyncEventDispatcher.addEvent( _callback, _eventType, _targetFile, e.key, e.value );
256                                 } else
257                                 if( _type === pettanr.file.TREE_EVENT.UPDATE && _eventType === pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES ){
258                                         AsyncEventDispatcher.addEvent( _callback, _eventType, _targetFile );
259                                 }
260                         }
261                 }
262                 
263                 return {
264                         init: function(){
265                                 instance = this;
266                                 currentFile = rootFile = new FileClass( instance, null, rootFileData );
267                                 // rootFile.init();
268                                 currentFile.getSeqentialFiles();
269                                 delete this.init;
270                         },
271                         getUID: function(){
272                                 return pettanr.util.getIndex( TREE_ACCESS_ARRAY, ACCESS );
273                         },
274                         getRootFile : function(){
275                                 return rootFile;
276                         },
277                         getCurrentFile: function(){
278                                 return currentFile;
279                         },
280                         hierarchy: function(){
281                                 return PARENT_FILE_RESITER.length;
282                         },
283                         getParentFileAt: function( _index){
284                                 var l = PARENT_FILE_RESITER.length;
285                                 if( typeof _index !== 'number' || _index < 0 || _index >= l) return null;
286                                 return PARENT_FILE_RESITER[ l -1 -_index];
287                         },
288                         down: function( _index){
289                                 if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return;
290                                 PARENT_FILE_RESITER.unshift( currentFile );
291                                 currentFile = currentFile.getChildFileByIndex( _index );
292                                 currentFile.getSeqentialFiles();
293                                 return currentFile;
294                         },
295                         up: function( _index){
296                                 var l = PARENT_FILE_RESITER.length;
297                                 if( l === 0) return null;
298                                 
299                                 if( currentFile ){
300                                         var _currentFile = currentFile;
301                                         currentFile = null;
302                                         _currentFile.destroy();
303                                 }
304                                 if( typeof _index === 'number'){
305                                         if( _index >= l) return null;
306                                         currentFile = this.getParentFileAt( _index );
307                                         PARENT_FILE_RESITER.splice( 0, l -_index);
308                                 } else {
309                                         currentFile = PARENT_FILE_RESITER.shift();
310                                 }
311                                 currentFile.getSeqentialFiles();
312                                 return currentFile;     
313                         },
314                         addTreeEventListener: function( _eventType, _callback){
315                                 FILE_CONTROLER.addEventListener( null, _eventType, _callback);
316                         },
317                         removeTreeEventListener: function( _eventType, _callback){
318                                 FILE_CONTROLER.removeEventListener( null, _eventType, _callback);
319                         },
320                         destroy: function(){
321                                 FILE_CONTROLER.destroyTree( instance.getUID() );
322                                 // removeEvent
323                                 var _currentFile = currentFile;
324                                 currentFile = rootFile = rootFileData = null;
325                                 // currentFile, rootFile を null にしないと .File.destroy() ができない.
326                                 _currentFile.destroy();
327                                 while( PARENT_FILE_RESITER.length > 0 ){
328                                         _currentFile = PARENT_FILE_RESITER.shift();
329                                         _currentFile.destroy();
330                                 }
331                                 instance = null;
332                         }
333                 }
334         };
335
336         var FileEventTicketClass = function( _uid, _eventType, _callback ){
337                 this.fileUID   = _uid;
338                 this.eventType = _eventType;
339                 this.callBack  = _callback;
340                 this.destroy   = function(){
341                         delete this.fileUID;
342                         delete this.eventType;
343                         delete this.destroy;
344                         delete this.callBack;
345                 }
346                 _uid = _eventType = _callback = undefined;
347         }
348         
349         var FileEventClass = function( eventType, file, key, value){
350                 this.eventType = eventType;
351                 this.targetFile = file;
352                 this.updatedAttribute = key;
353                 this.updatedValue = value;
354         }
355
356 /*
357  * fileのdataはobjectで保持している。
358  * pettanr.file.の外からファイルをみるときは、FileClassを通して操作する。
359  * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。
360  * treeがdestryされると、fileのイベントリスナーも全て削除される。
361  * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す.
362  * 
363  * parentData のほうがいい!
364  */
365         
366         var FileClass = function( tree, parentData, data ){
367                 var uid = FILE_CONTROLER.getFileUID( data ),
368                         instance = this;
369                 
370                 FILEDATA_ACCESS.push(
371                         {
372                                 TREE:                           tree,
373                                 parentData:                     parentData,
374                                 DATA:                           data,
375                                 dispatchFileEvent:      dispatchEvent
376                         }
377                 );
378                 
379                 tree = parentData = data = null;
380                 
381                 function dispatchEvent( e ){
382                         FILE_CONTROLER.fileEventRellay( uid, e );
383                 }
384                 this.getUID = function(){
385                         return uid;
386                 }
387         };
388         
389         FileClass.prototype = {
390                 isChildFile: function( _FILEorFILEDATA){
391                         return this.getChildFileIndex( _FILEorFILEDATA) !== -1;
392                 },
393                 getSeqentialFiles: function(){
394                         var _driver = FILE_CONTROLER.getDriver( this );
395                         if( _driver !== null && typeof _driver.getSeqentialFiles === 'function' ){
396                                 _driver.getSeqentialFiles( this );
397                         }
398                 },
399                 addEventListener: function( _eventType, _callback ){
400                         FILE_CONTROLER.addEventListener( this, _eventType, _callback );
401                 },
402                 removeEventListener: function( _eventType, _callback ){
403                         FILE_CONTROLER.removeEventListener( this, _eventType, _callback );
404                 },
405                 getChildFileLength: function(){
406                         var children = FILE_CONTROLER.getChildren( this );
407                         return Type.isArray( children ) === true ? children.length : -1;
408                 },
409                 getChildFileIndex: function( _FILEorFILEDATA ){
410                         var children = FILE_CONTROLER.getChildren( this);
411                         if( Type.isArray( children ) === false ) return -1;
412                         var l = children.length,
413                                 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA );
414                         if( _fileData === null ) return -1;
415                         for( var i=0; i<l; ++i ){
416                                 if( children[ i ] === _fileData ) return i;
417                         }
418                         return -1;
419                 },
420                 getChildFileByIndex: function( _index ){
421                         var _access = FILE_CONTROLER.getFileDataAccess( this ),
422                                 _children = FILE_CONTROLER.getChildren( this );
423                         if( typeof _index !== 'number' || _index < 0 || Type.isArray( _children ) === false || _index >= _children.length) return null;
424                         var _file = new FileClass( _access.TREE, _access.DATA, _children[ _index ]);
425                         // _file.init();
426                         return _file;
427                 },
428                 getName: function(){
429                         var driver = FILE_CONTROLER.getDriver( this );
430                         if( typeof driver.getName === 'function'){
431                                 return driver.getName( this );
432                         }
433                         return FileDriverBase.getName( this);
434                 },
435                 getThumbnail: function(){
436                         var driver = FILE_CONTROLER.getDriver( this);
437                         if( typeof driver.getThumbnail === 'function'){
438                                 return driver.getThumbnail( this);
439                         }
440                         return FileDriverBase.getThumbnail( this);
441                 },
442                 getType: function(){
443                         var _data = FILE_CONTROLER.getFileData( this);
444                         return typeof _data.type === 'number' ? _data.type : pettanr.file.FILE_TYPE.UNKNOWN;
445                 },
446                 getState: function(){
447                         var _data = FILE_CONTROLER.getFileData( this);
448                         return typeof _data.state === 'number' ? _data.state : pettanr.file.FILE_STATE.OK;
449                 },
450                 getSummary: function(){
451                         var driver = FILE_CONTROLER.getDriver( this );
452                         if( typeof driver.getSummary === 'function'){
453                                 return driver.getSummary( this );
454                         }
455                         return FileDriverBase.getSummary( this);
456                 },
457                 isWritable: function(){
458                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.WRITE );
459                 },
460                 isSortable: function(){
461                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.SORT );
462                 },              
463                 isCreatable: function(){
464                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.CREATE );
465                 },
466                 isRenamable: function(){
467                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.RENAME );
468                 },
469                 isDeletable: function(){
470                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.DELETE );
471                 },
472                 read: function(){
473                         // simpleDeepCopy
474                         var driver = FILE_CONTROLER.getDriver( this ),
475                                 data;
476                         if( typeof driver.read === 'function'){
477                                  data = driver.read( this );
478                         }
479                         return FileDriverBase.read( data || this );
480                 },
481                 write: function( _newData, _onUpdateFunction ){
482                         var driver = FILE_CONTROLER.getDriver( this );
483                         if( typeof driver.write === 'function'){
484                                 return driver.write( this, _newData, _onUpdateFunction );
485                         }
486                         return FileDriverBase.write( this, _newData, _onUpdateFunction );
487                 },
488                 viewerApplicationList: function(){
489                         var driver = FILE_CONTROLER.getDriver( this );
490                         if( typeof driver.viewerApplicationList === 'function'){
491                                 return driver.viewerApplicationList( this );
492                         }
493                         return FileDriverBase.viewerApplicationList( this );
494                 },
495                 editorApplicationList: function(){
496                         var driver = FILE_CONTROLER.getDriver( this );
497                         if( typeof driver.editorApplicationList === 'function'){
498                                 return driver.editorApplicationList( this );
499                         }
500                         return FileDriverBase.viwerApps( this );
501                 },
502                 create: function(){
503                         
504                 },
505                 sort: function(){
506                         
507                 },
508                 onCopy: function(){
509                         
510                 },
511                 onDelete: function(){
512                         
513                 },
514                 move: function( _newFolder, _newIndex, opt_callback ){
515                         var _access = FILE_CONTROLER.getFileDataAccess( this );
516                         _access.TREE.move( _access.parentData, this.getUID(), _newFolder, _newIndex, opt_callback );
517                 },
518                 replace: function( _newIndex, opt_callback ){
519                         var _access = FILE_CONTROLER.getFileDataAccess( this );
520                         _access.TREE.replace( _access.parentData, this.getUID(), _newIndex, opt_callback);
521                 },
522                 /**
523                  * サーチ
524                  * 探しているファイルの属性と値を指定.一致する child の index を配列で返す.
525                  */
526                 search: function( obj, rule ){
527                         var _children = FILE_CONTROLER.getChildren( this ),
528                                 _child,
529                                 ret = [], k, c;
530                         for( var i=0, l=_children.length; i<l; ++i ){
531                                 _child = _children[ i ];
532                                 c = true;
533                                 for( k in obj ){
534                                         if( obj[ k ] !== _child[ k ] ){
535                                                 c = false;
536                                                 break;
537                                         }
538                                 }
539                                 c === true && ret.push( i );
540                         }
541                         return ret;
542                 },
543                 destroy: function(){
544                         var _access = FILE_CONTROLER.getFileDataAccess( this );
545                         var TREE = _access.TREE;
546                         if( TREE.getCurrentFile() === this ) return;
547                         if( TREE.getRootFile() === this ) return;
548                         for( var i=0, l = TREE.hierarchy(); i<l; ++i ){
549                                 if( TREE.getParentFileAt( i ) === this ){
550                                         return;
551                                 }
552                         }
553                         var _index = pettanr.util.getIndex( FILEDATA_ACCESS, _access );
554                         if( _index === -1 || _access === null ) return;
555                         // event の 削除
556                         FILEDATA_ACCESS.splice( _index, 1 );
557                         delete _access.DATA;
558                         delete _access.TREE;
559                         delete _access.parentData;
560                         delete _access.dispatchFileEvent;
561                 }
562         }
563
564         /*
565          * FileDriverBase
566          */
567         var FileDriverBase = {
568                 getSeqentialFiles: function( _file){
569                 },
570                 getName: function( _file){
571                         var _data = FILE_CONTROLER.getFileData( _file);
572                         return _data.name || 'No Name';
573                 },
574                 getThumbnail: function( _file){
575                         var _data = FILE_CONTROLER.getFileData( _file),
576                                 _type = _data.type,
577                                 _className = '';
578                         if( _type === pettanr.file.FILE_TYPE.FOLDER){
579                                 _className = 'folder';
580                         } else
581                         if( _type === pettanr.file.FILE_TYPE.IMAGE){
582                                 
583                         } else
584                         if( _type === pettanr.file.FILE_TYPE.TEXT){
585                                 
586                         } else
587                         if( _type === pettanr.file.FILE_TYPE.HTML){
588                                 
589                         } else
590                         if( _type === pettanr.file.FILE_TYPE.CSV){
591                                 
592                         } else
593                         if( _type === pettanr.file.FILE_TYPE.JSON){
594                                 
595                         } else
596                         if( _type === pettanr.file.FILE_TYPE.XML){
597                                 
598                         }
599                         return {
600                                 image:          null,
601                                 className:      ' file-type-' + _className
602                         }
603                 },
604                 getSummary: function( _file ){
605                         var _data = FILE_CONTROLER.getFileData( _file ),
606                                 _type = _data.type;
607                         if( _type === pettanr.file.FILE_TYPE.FOLDER){
608                                 return 'folder';
609                         } else
610                         if( _type === pettanr.file.FILE_TYPE.IMAGE){
611                                 return 'image file';
612                         } else
613                         if( _type === pettanr.file.FILE_TYPE.TEXT){
614                                 return 'text file';
615                         } else
616                         if( _type === pettanr.file.FILE_TYPE.HTML){
617                                 return 'html document file';
618                         } else
619                         if( _type === pettanr.file.FILE_TYPE.CSV){
620                                 return 'csv daat file';
621                         } else
622                         if( _type === pettanr.file.FILE_TYPE.JSON){
623                                 return 'json data file';
624                         } else
625                         if( _type === pettanr.file.FILE_TYPE.XML){
626                                 return 'xml data file';
627                         }
628                         return '';
629                 },
630                 getUpdatePolicy: function( _file ){
631                         // debug用 全てのメニューを許可
632                         return pettanr.file.FILE_UPDATE_POLICY.DSRWC;
633                 },
634                 read: function( _FILEorDATA ){
635                         var data,
636                                 protects = pettanr.file.FILE_DATA_PROPERTY_RESERVED;                    
637                         if( _FILEorDATA instanceof FileClass ){
638                                 data = FILE_CONTROLER.getFileData( _FILEorDATA )
639                         } else {
640                                 data = _FILEorDATA;
641                         }
642
643                         function clone( src ) {
644                                 var ret;
645                                 if( Type.isArray(src) === true ){
646                                         ret = [];
647                                 } else
648                                 if( Type.isObject(src) === true ){
649                                         ret = {};
650                                 } else
651                                 if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){
652                                         return src;
653                                 } else {
654                                         return null;
655                                 }
656                                 for( var key in src ){
657                                         if( pettanr.util.getIndex( protects, key ) === -1 ){
658                                                 //alert( key )
659                                                 ret[ key ] = clone( src[ key ]);
660                                         }
661                                 }
662                                 return ret;
663                         };
664                                 
665                         return clone( data );
666                 },
667                 write: function( _file, _newData, _onUpdateFunction ){
668                         var _data = FILE_CONTROLER.getFileData( _file ),
669                                 _type = _data.type;
670                         return false;
671                 },
672                 viewerApplicationList: function(){
673                         return [];
674                 },
675                 editorApplicationList: function(){
676                         return [];
677                 },
678                 onCreate: function(){
679                         
680                 },
681                 onSort: function(){
682                         
683                 },
684                 onCopy: function(){
685                         
686                 },
687                 onDelete: function(){
688                         
689                 }
690         }
691
692         var ROOT_FILEDATA = {
693                         name:           'system root',
694                         type:           FILE_TYPE_IS_FOLDER,
695                         children:       []
696                 },
697                 SYSTEM_TREE = FILE_CONTROLER.createTree( ROOT_FILEDATA),
698                 ROOT_FILE = SYSTEM_TREE.getRootFile();
699         
700         function createFolderUnderRoot( _fileData){
701                 ROOT_FILEDATA.children.push( _fileData);
702                 FILE_CONTROLER.getFileDataAccess( ROOT_FILE)
703                         .dispatchFileEvent( new FileEventClass( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null));
704         }
705         function createFileEvent( _eventType, _file, _key, _value){
706                 return new FileEventClass( _eventType, _file, _key, _value);
707         }
708         function createFileTypeID(){
709                 return ++numFileType;
710         }
711         
712         return {
713                 init: function(){
714                         //REQUEST_CONTROLER.init();
715                         //FILE_CONTROLER.init();
716                         delete pettanr.file.init;
717                 },
718                 registerDriver: function( _driver ){
719                         _driver.prototype = FileDriverBase;
720                         /*
721                          * File API
722                          */
723                         return {
724                                 createFolderUnderRoot:  createFolderUnderRoot,
725                                 getFileDataAccess:              FILE_CONTROLER.getFileDataAccess,
726                                 getFileData:                    FILE_CONTROLER.getFileData,
727                                 getJson:                                REQUEST_CONTROLER.getJson,
728                                 createFileEvent:                createFileEvent,
729                                 createFileTypeID:               createFileTypeID
730                         }
731                 },
732                 createTree: function( _rootFile){
733                         return FILE_CONTROLER.createTree( _rootFile);
734                 },
735                 isTreeInstance: function( _tree){
736                         return _tree instanceof TreeClass;
737                 },
738                 isFileInstance: function( _file){
739                         return _file instanceof FileClass;
740                 },
741                 FILE_TYPE: {
742                         UNKNOWN:        0,
743                         FOLDER:         FILE_TYPE_IS_FOLDER,
744                         IMAGE:          createFileTypeID(),
745                         TEXT:           createFileTypeID(),
746                         HTML:           createFileTypeID(),
747                         CSV:            createFileTypeID(),
748                         JSON:           createFileTypeID(),
749                         XML:            createFileTypeID()
750                 },
751                 FILE_STATE: {
752                         UNKNOWN:        0,
753                         OK:                     1,
754                         LOADING:        2,
755                         ERROR:          3,
756                         BROKEN:         4
757                 },
758                 FILE_UPDATE_POLICY: {
759                         _____:          parseInt( '00000', 2),
760                         ____C:          parseInt( '00001', 2), // hasCreateMenu
761                         ___W_:          parseInt( '00010', 2), // isWritable
762                         ___WC:          parseInt( '00011', 2), // isWritable
763                         __R__:          parseInt( '00100', 2), // isRenamable
764                         __R_C:          parseInt( '00101', 2), // hasCreateMenu
765                         __RW_:          parseInt( '00110', 2), // isWritable
766                         __RWC:          parseInt( '00111', 2), // isWritable
767                         _S___:          parseInt( '01000', 2), // childrenIsSortable
768                         _S__C:          parseInt( '01001', 2),
769                         _S_W_:          parseInt( '01010', 2),
770                         _S_WC:          parseInt( '01011', 2),
771                         _SR__:          parseInt( '01100', 2),
772                         _SR_C:          parseInt( '01101', 2),
773                         _SRW_:          parseInt( '01110', 2),
774                         _SRWC:          parseInt( '01111', 2),
775                         D____:          parseInt( '10000', 2),
776                         D___C:          parseInt( '10001', 2), // hasCreateMenu
777                         D__W_:          parseInt( '10010', 2), // isWritable
778                         D__WC:          parseInt( '10011', 2), // isWritable
779                         D_R__:          parseInt( '10100', 2), // isRenamable
780                         D_R_C:          parseInt( '10101', 2), // hasCreateMenu
781                         D_RW_:          parseInt( '10110', 2), // isWritable
782                         D_RWC:          parseInt( '10111', 2), // isWritable
783                         DS___:          parseInt( '11000', 2), // childrenIsSortable
784                         DS__C:          parseInt( '11001', 2),
785                         DS_W_:          parseInt( '11010', 2),
786                         DS_WC:          parseInt( '11011', 2),
787                         DSR__:          parseInt( '11100', 2),
788                         DSR_C:          parseInt( '11101', 2),
789                         DSRW_:          parseInt( '11110', 2),
790                         DSRWC:          parseInt( '11111', 2),
791                         CREATE:         1,
792                         WRAITE:         2,
793                         RENAME:         4,
794                         SORT:           8,
795                         DELETE:         16
796                 },
797                 TREE_EVENT: {
798                         UPDATE:                         'onTreeUpdate'
799                 },
800                 FILE_EVENT: {
801                         UPDATE_ATTRIVUTE:       'onFileUpdate',
802                         GET_SEQENTIAL_FILES:'gotSeqentilFiles'
803                 },
804                 FILE_DATA_PROPERTY_RESERVED: [
805                         'children', 'driver', 'state', 'type'
806                 ]
807         }
808 })();
809
810 pettanr.finder = ( function(){
811         var FINDER_ARRAY = [],
812                 ELM_ORIGIN_FINDER_LOCATION_ITEM = pettanr.util.pullHtmlAsTemplete( 'templete-finder-location-item'),
813                 ELM_ORIGIN_FINDER_ICON = ( function(){
814                                 var forIE = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon-ie'),
815                                         modern = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon');
816                                 return pettanr.ua.isIE === true && pettanr.ua.ieVersion < 8 ? forIE : modern;
817                         })(),
818                 ELM_ORIGIN_CONTAINER = pettanr.util.pullHtmlAsTemplete( 'templete-finder-container'),
819                 ICON_HEIGHT = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON).height,
820                 ICON_CLASSNAME = 'finder-icon-thumbnail',
821                 FINDER_ICON_POOL = [],
822                 BREAD_OBJECT_POOL = [];
823         
824         var FinderIconClass = function(){
825                 var elmContainer,
826                         ELM_WRAPPER = ELM_ORIGIN_FINDER_ICON.cloneNode( true),
827                         ELM_THUMBNAIL = pettanr.util.getElementsByClassName( ELM_WRAPPER, ICON_CLASSNAME )[0],
828                         ELM_FILENAME = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename' )[0],
829                         ELM_DESCRIPTION = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-summary' )[0],
830                         ELM_EDITOR_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-editor-apps' )[0],
831                         ELM_VIEWER_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-viewer-apps' )[0],
832                         ELM_ACTION_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-action' )[0],
833                         file, w, index, style, instansce,
834                         onDownCallback, onEditorCallback, onViewerCallback, onActionCallback,
835                         viewerList, editorList;
836                 
837                 ELM_WRAPPER.onclick = onDownClick;
838                 function onDownClick(){
839                         onDownCallback( index);
840                         return false;
841                 }
842                 ELM_EDITOR_BUTTON.onclick = onEditorClick;
843                 function onEditorClick(){
844                         onEditorCallback( file, editorList[ 0 ] );
845                         return false;
846                 }
847                 ELM_VIEWER_BUTTON.onclick = onViwerClick;
848                 function onViwerClick(){
849                         onViewerCallback( file, viewerList[ 0 ] );
850                         return false;
851                 }
852                 ELM_ACTION_BUTTON.onclick = onActionClick;
853                 function onActionClick(){
854                         onActionCallback( file );
855                         return false;
856                 }
857                 function draw(){
858                         var _thumb = file.getThumbnail();
859                         if( _thumb.image ){
860                                 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';
861                                 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');
862                         } else {
863                                 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' + _thumb.className;
864                                 ELM_THUMBNAIL.style.backgroundImage = '';
865                         }
866                         ELM_FILENAME.firstChild.data = file.getName();
867                         ELM_DESCRIPTION.firstChild.data = file.getSummary();
868                         
869                         if( Type.isArray( viewerList ) === true && viewerList.length > 0 ){
870                                 ELM_VIEWER_BUTTON.style.display = '';
871                         } else {
872                                 ELM_VIEWER_BUTTON.style.display = 'none';
873                         };
874                         if( Type.isArray( editorList ) === true && editorList.length > 0 ){
875                                 ELM_EDITOR_BUTTON.style.display = '';
876                         } else {
877                                 ELM_EDITOR_BUTTON.style.display = 'none';
878                         };
879                 }
880                 function resize(){
881                         // ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';
882                 }
883                 function onCollect(){
884                         elmContainer.removeChild( ELM_WRAPPER );
885                         elmContainer = null;
886                         FINDER_ICON_POOL.push( instansce );
887                 }
888                 
889                 return {
890                         init: function( _file, _elmContainer, _w, _index, _style, _onDownCallback, _onEditorCallback, _onViewerCallback, _onActionCallback ){
891                                 instansce = this;
892                                 if( elmContainer !== _elmContainer){
893                                         _elmContainer.appendChild( ELM_WRAPPER);
894                                         elmContainer = _elmContainer;
895                                 }
896                                 if( file !== _file){
897                                         file && file.destroy();
898                                         file = _file;
899                                         viewerList = file.viewerApplicationList();
900                                         editorList = file.editorApplicationList();
901                                         draw();
902                                 }
903                                 if( index !== _index){
904                                         index = _index;
905                                         resize();
906                                 }
907                                 onDownCallback = _onDownCallback;
908                                 onEditorCallback = _onEditorCallback;
909                                 onViewerCallback = _onViewerCallback;
910                                 onActionCallback = _onActionCallback;
911                         },
912                         elm: ELM_WRAPPER,
913                         index: function( _index){
914                                 
915                                 return index;
916                         },
917                         style: function( _style){
918                                 
919                                 return style;
920                         },
921                         onResize: function( w ){
922                                 
923                         },
924                         destroy: function(){
925                                 elmContainer.removeChild( ELM_WRAPPER );
926                                 file && file.destroy();
927                                 file = elmContainer = onDownCallback = onEditorCallback = onViewerCallback = onActionCallback = viewerList = editorList = null;
928                                 FINDER_ICON_POOL.push( instansce);
929                         }
930                 }
931         }
932         function updateIconPosition( _style, _w, _index, _elm){
933                 
934         }
935         var BreadcrumbClass = function(){
936                 var elmContainer,
937                         ELM_WRAPPER = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true ),
938                         ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a')[0],
939                         file, w, index, instansce,
940                         callback;
941                 ELM_WRAPPER.onclick = onClick;
942                 function draw(){
943                         ELM_FILENAME.className = 'file-icon-' + file.getType();
944                         ELM_FILENAME.innerHTML = file.getName();
945                 }
946                 function resize( index){
947                         ELM_WRAPPER.style.left = (index * 90) +'px';
948                 }
949                 function onClick(){
950                         callback( index);
951                         return false;
952                 }
953
954                 return {
955                         init: function( _file, _elmContainer, _index, _callback ){
956                                 instansce = this;
957                                 if( elmContainer !== _elmContainer ){
958                                         _elmContainer.appendChild( ELM_WRAPPER);
959                                         elmContainer = _elmContainer;
960                                 }
961                                 if( file !== _file){
962                                         file = _file;
963                                         draw();
964                                 }
965                                 if( index !== _index){
966                                         index = _index;
967                                         resize( index);
968                                 }
969                                 callback = _callback;
970                         },
971                         elm: ELM_WRAPPER,
972                         index: function( _index){
973                                 
974                                 return index;
975                         },
976                         onResize: function( w){
977                                 
978                         },
979                         destroy: function(){
980                                 elmContainer.removeChild( ELM_WRAPPER);
981                                 file = elmContainer = null;
982                                 BREAD_OBJECT_POOL.push( this );
983                         }
984                 }
985         }
986         
987         var FinderClass = function( ELM_CONTAINER, tree, header, footer, onSelect, viewerOption, editorOption ){
988                 var ICON_ARRAY = [],
989                         BREAD_ARRAY = [],
990                         elmContainer = ELM_ORIGIN_CONTAINER.cloneNode( true ),
991                         elmLocation = elmContainer.getElementsByTagName( 'ul' )[0],
992                         nodesDiv = elmContainer.getElementsByTagName( 'div' ),
993                         elmSidebarButton = nodesDiv[1],
994                         elmStyleButton = nodesDiv[2],
995                         elmActionButton = nodesDiv[3],
996                         elmBody = nodesDiv[ nodesDiv.length -1 ],
997                         //tree = pettanr.file.createTree( TREE_TYPE),
998                         headX,
999                         headY,
1000                         headH = pettanr.util.getElementSize( nodesDiv[0] ).height,
1001                         bodyY,
1002                         currentFile = null,
1003                         breadW = 90,
1004                         size = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON ),
1005                         iconW = size.width,
1006                         iconH = size.height,
1007                         style = 0,
1008                         w, h, bodyH,
1009                         instance = this;
1010                         
1011                 tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, draw );
1012                 ELM_CONTAINER.appendChild( elmContainer );
1013                 
1014                 function draw( _w, _h ){
1015                         w = Type.isFinite( _w ) === true ? _w : w;
1016                         h = Type.isFinite( _h ) === true ? _h : h;
1017                         bodyH = h - headH;
1018                         var     l = tree.hierarchy() +1,
1019                                 m = BREAD_ARRAY.length,
1020                                 _file, _bread;
1021                         for(var i=0; i<l; ++i){
1022                                 _file = i !== l-1 ? tree.getParentFileAt( i) : tree.getCurrentFile();
1023                                 if( i < m){
1024                                         BREAD_ARRAY[ i].init( _file, elmLocation, i, onHeadClick);
1025                                 } else {
1026                                         BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick ));
1027                                 }
1028                         }
1029                         while( l < BREAD_ARRAY.length){
1030                                 BREAD_ARRAY.pop().destroy();
1031                         }
1032                         
1033                         l = _file.getChildFileLength();
1034                         m = ICON_ARRAY.length;
1035
1036                         for( i=0; i<l; ++i){
1037                                 if( i < m){
1038                                         ICON_ARRAY[ i ].init( _file.getChildFileByIndex( i), elmBody, w, i, style, onDown, onEditor, onViwer, onAction );
1039                                 } else {
1040                                         ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i), elmBody, _w, i, style, onDown, onEditor, onViwer, onAction ));
1041                                 }
1042                         }
1043                         if( _file.getState() === pettanr.file.FILE_STATE.LOADING ){
1044                                 elmBody.className = 'finder-body loading';
1045                         } else {
1046                                 elmBody.className = 'finder-body';
1047                         }
1048                         
1049                         elmBody.style.height = bodyH + 'px';
1050                         
1051                         while( l < ICON_ARRAY.length){
1052                                 ICON_ARRAY.pop().destroy();
1053                         }
1054                 }
1055                 
1056                 function onHeadClick( i){
1057                         var l = BREAD_ARRAY.length -1;
1058                         if( i < l){
1059                                 var _file = tree.getParentFileAt( i);
1060                                 if( _file !== null){
1061                                         tree.up( i);
1062                                         draw( w, h );
1063                                 }
1064                         }
1065                 }
1066                 function onDown( i ){
1067                         if( i < ICON_ARRAY.length ){
1068                                 var _file = tree.getCurrentFile().getChildFileByIndex( i );
1069                                 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === pettanr.file.FILE_TYPE.FOLDER)){
1070                                         tree.down( i );
1071                                         draw( w, h );
1072                                 } else {
1073                                         Type.isFunction( onSelect ) === true && onSelect( _file  );
1074                                 }
1075                         }
1076                 }
1077                 function onEditor( _file, _app, editorOption ){
1078                         _app.boot( _file, editorOption );
1079                 }
1080                 function onViwer( _file, _app ){
1081                         _app.bootInOverlay( _file, viewerOption );
1082                 }
1083                 function onAction( _file ){
1084
1085                 }
1086                 this.rootElement   = elmContainer;
1087                 this.parentElement = ELM_CONTAINER;
1088                 this.displayName   = 'finder';
1089                 this.ID            = 'finder';
1090                 this.MIN_WIDTH     = 240;
1091                 this.MIN_HEIGHT    = 240;
1092                 this.init = function(){
1093                         //$( elmLocation).click( onHeadClick);
1094                         //$( elmContainer).click( onBodyClick);
1095                         var position = pettanr.util.getAbsolutePosition( elmLocation );
1096                         headX = position.x;
1097                         headY = position.y;
1098                         bodyY = pettanr.util.getAbsolutePosition( elmBody ).y;
1099                         delete instance.init;
1100                 }
1101                 this.onPaneResize = function( _w, _h ){
1102                         instance.init && instance.init();
1103                         draw( _w, _h );                 
1104                         
1105                         w = _w;
1106                         h = _h;
1107                         elmBody.style.height = ( _h - headH ) + 'px';
1108                         
1109                         for(var i=0, l=ICON_ARRAY.length; i<l; ++i){
1110                                 ICON_ARRAY[ i].onResize( _w );
1111                         }
1112                 }
1113         }
1114         FinderClass.prototype = pettanr.view._getAbstractApplication();
1115         
1116         function getFinderIcon( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction){
1117                 var _icon;
1118                 if( FINDER_ICON_POOL.length > 0){
1119                         _icon = FINDER_ICON_POOL.shift();
1120                 } else {
1121                         _icon = new FinderIconClass();
1122                 }
1123                 _icon.init( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction );
1124                 return _icon;
1125         }
1126         
1127         function getBreadcrumb( _file, _elmContainer, index, callback){
1128                 var _bread;
1129                 if( BREAD_OBJECT_POOL.length > 0){
1130                         _bread = BREAD_OBJECT_POOL.shift();
1131                 } else {
1132                         _bread = new BreadcrumbClass();
1133                 }
1134                 _bread.init( _file, _elmContainer, index, callback);
1135                 return _bread;
1136         }
1137
1138         return {
1139                 init: function(){
1140                         
1141                 },
1142                 createFinder: function( _applicationReference, _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption ){
1143                         if( pettanr.view.isApplicationReference( _applicationReference ) === false ) return;
1144                         
1145                         var _finder = new FinderClass( _elmTarget, _tree, _header, _footer, _onSelect, _viewerOption, _editorOption );
1146                         FINDER_ARRAY.push( _finder );
1147                         return _finder;
1148                 },
1149                 registerFinderHead: function(){
1150                         
1151                 },
1152                 registerFinderPane: function( _finderPane){
1153                         
1154                 },
1155                 isFinderInstance: function( _finder){
1156                         return _finder instanceof FinderClass;
1157                 },
1158                 isFinderPaneInstance: function(){
1159                         
1160                 },
1161                 isFinderHeadInstance: function(){
1162                 }
1163         }
1164 })();
1165
1166
1167 pettanr.driver = ( function(){
1168         var MyAuthorID = 'current_author' in window ? current_author.id : ( pettanr.CONST.SERVER_SUPPORT === false ? 1 : -1 ),
1169                 MyArtistID = 'current_artist' in window ? current_artist.id : ( pettanr.CONST.SERVER_SUPPORT === false ? 1 : -1 ),
1170                 Driver = {
1171                         getSeqentialFiles: function( _file){
1172                                 var _data = FileAPI.getFileData( _file),
1173                                         _json = _data !== null ? _data.json : null;
1174                                 if( _json === true && _data.type === pettanr.driver.FILE_TYPE.COMIC ){
1175                                         if( pettanr.CONST.SERVER_SUPPORT === false ){
1176                                                 _json = [ 'json\/comics_', _data.id, '.json' ].join( '' );
1177                                         } else {
1178                                                 _json = [ pettanr.CONST.PETTANR_ROOT_PATH, 'comics\/', _data.id, '.json\/play\/' ].join( '' );
1179                                         }
1180                                 }
1181                                 if( typeof _json === 'string'){
1182                                         FileAPI.getJson( _file, _json, onLoadJson, onErrorJson);
1183                                         _data.state = pettanr.file.FILE_STATE.LOADING;
1184                                         _data.json = null;
1185                                         return;
1186                                 }
1187                         },
1188                         getName: function( _file){
1189                                 var _data = FileAPI.getFileData( _file),
1190                                         _type = _data !== null ? _data.type : null;
1191                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
1192                                         return [ _data.id, _data.ext ].join( '.');
1193                                 } else
1194                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1195                                         return [ _data.t, ':', _data.comic.title ].join( '');
1196                                 } else
1197                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1198                                         return _data.title;
1199                                 } else
1200                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
1201                                         return [ _data.name, '画伯' ].join( '');
1202                                 } else
1203                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR ){
1204                                         return [ _data.name, '先生' ].join( '');
1205                                 }
1206                                 return _data.name;
1207                         },
1208                         getThumbnail: function( _file){
1209                                 var _data = FileAPI.getFileData( _file),
1210                                         _type = _data !== null ? _data.type : null;
1211                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1212                                         return { image: [ pettanr.CONST.RESOURCE_PICTURE_PATH, 'thumbnail/', _data.id, '.', _data.ext ].join( '')};
1213                                 }
1214                                 if( _data === FILE_DATA_COMICS_ROOT){
1215                                         return { className: 'file-type-cabinet'};
1216                                 }
1217                                 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1218                                         return { className: 'file-type-comic'};
1219                                 }
1220                                 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1221                                         return { className: 'file-type-panel'};
1222                                 }
1223                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1224                                         return { className: 'file-type-author'};
1225                                 }
1226                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1227                                         return { className: 'file-type-artist'};
1228                                 }
1229                                 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1230                                         return { className: 'file-type-folder'};
1231                                 }
1232                                 return { className: 'file-type-broken'};
1233                         },
1234                         getSummary: function( _file ){
1235                                 var _data = FileAPI.getFileData( _file ),
1236                                         _type = _data !== null ? _data.type : null;
1237                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1238                                         return [ _data.width, 'x', _data.height, ', filesize:', _data.filesize, ', lisence:', _data.license ].join( '' );
1239                                 }
1240                                 if( _data === FILE_DATA_COMICS_ROOT){
1241                                         return 'cabinet file';
1242                                 }
1243                                 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1244                                         return 'comic file, id:' + _data.id;
1245                                 }
1246                                 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1247                                         return [ _data.width, 'x', _data.height ].join( '' );
1248                                 }
1249                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1250                                         return 'author file, id:' + _data.id;
1251                                 }
1252                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1253                                         return [ 'id:', _data.id, ' Email:', _data.email || 'empty' , ', HP:', _data.homepage_url || 'empty' ].join( '' );
1254                                 }
1255                                 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1256                                         return 'pettanR folder';
1257                                 }
1258                                 return 'pettanR unknown file';
1259                         },
1260                         read: function( _file ){
1261                                 var _data = FileAPI.getFileData( _file ),
1262                                         _type = _data !== null ? _data.type : null,
1263                                         ret;
1264                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1265                                         // children を panels に deepcopy
1266                                         ret = {};
1267                                         for( var key in _data ){
1268                                                 ret[ key ] = _data[ key ]
1269                                         }
1270                                         ret.panels = _data.children;
1271                                         return ret;
1272                                 }
1273                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1274                                 }
1275                                 if( _type === pettanr.driver.FILE_TYPE.PANEL_PICTURE ){
1276                                         
1277                                 }
1278                                 if( _type === pettanr.driver.FILE_TYPE.BALLOON ){
1279                                 }
1280                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
1281                                 }
1282                         },
1283                         write: function( _file, _newData, _onUpdateFunction ){
1284                                 var _data = FileAPI.getFileData( _file ),
1285                                         _type = _data !== null ? _data.type : null;
1286                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1287                                 }
1288                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1289                                 }
1290                                 if( _type === pettanr.driver.FILE_TYPE.PANEL_PICTURE ){
1291                                         
1292                                 }
1293                                 if( _type === pettanr.driver.FILE_TYPE.BALLOON ){
1294                                 }
1295                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
1296                                 }                               
1297                         },
1298                         viewerApplicationList: function( _file ){
1299                                 var _data = FileAPI.getFileData( _file ),
1300                                         _type = _data !== null ? _data.type : null;
1301                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1302                                         return [ pettanr.reader ];
1303                                 }
1304                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1305                                         return [ pettanr.reader ];
1306                                 }       
1307                                 if( _data === FILE_DATA_MY_PICTURES_ROOT ){
1308                                         return [ pettanr.premiumSatge ];
1309                                 }
1310                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
1311                                         return [ pettanr.premiumSatge ];
1312                                 }
1313                                 return [];
1314                         },
1315                         editorApplicationList: function( _file ){
1316                                 var _data = FileAPI.getFileData( _file ),
1317                                         _type = _data !== null ? _data.type : null;
1318                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1319                                         return [ pettanr.editor ];
1320                                 }
1321                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1322                                         return [ pettanr.editor, pettanr.comicConsole ];
1323                                 }
1324                                 return [];
1325                         }
1326                 },
1327                 FileAPI = pettanr.file.registerDriver( Driver ),
1328                 FILE_DATA_SERVICE_ROOT = {
1329                         name:           'PettanR root',
1330                         type:           pettanr.file.FILE_TYPE.FOLDER,
1331                         children:       []
1332                 },
1333                 FILE_DATA_COMICS_ROOT = {
1334                         name:           'Comics',
1335                         type:           pettanr.file.FILE_TYPE.FOLDER,
1336                         children:       [],
1337                         driver:         Driver,
1338                         json:           pettanr.CONST.URL_COMICS_JSON
1339                 },
1340                 FILE_DATA_PANELS_ROOT = {
1341                         name:           'Panels',
1342                         type:           pettanr.file.FILE_TYPE.FOLDER,
1343                         children:       [],
1344                         driver:         Driver,
1345                         json:           pettanr.CONST.URL_PANELS_JSON
1346                 },
1347                 FILE_DATA_PICTURE_ROOT = {
1348                         name:           'Picutures',
1349                         type:           pettanr.file.FILE_TYPE.FOLDER,
1350                         children:       [],
1351                         driver:         Driver,
1352                         json:           pettanr.CONST.URL_RESOURCE_PICTURES_JSON
1353                 },
1354                 FILE_DATA_MY_COMICS_ROOT = {
1355                         name:           'My Comics',
1356                         type:           pettanr.file.FILE_TYPE.FOLDER,
1357                         children:       [],
1358                         driver:         Driver,
1359                         id:                     MyAuthorID
1360                 },
1361                 FILE_DATA_LATEST_COMICS = {
1362                         name:           'Latest Comics',
1363                         type:           pettanr.file.FILE_TYPE.FOLDER,
1364                         children:       []
1365                 },
1366                 FILE_DATA_MY_PICTURES_ROOT = {
1367                         name:           'My Pictures',
1368                         type:           pettanr.file.FILE_TYPE.FOLDER,
1369                         children:       [],
1370                         driver:         Driver,
1371                         json:           pettanr.CONST.URL_ORIGINAL_PICTURES_JSON,
1372                         id:                     MyArtistID
1373                 },
1374                 FILE_DATA_AUTHOR_ROOT = {
1375                         name:           'Authors',
1376                         type:           pettanr.file.FILE_TYPE.FOLDER,
1377                         children:       []
1378                 },
1379                 FILE_DATA_ARTIST_ROOT = {
1380                         name:           'Artists',
1381                         type:           pettanr.file.FILE_TYPE.FOLDER,
1382                         children:       []
1383                 },
1384                 FILE_DATA_LISENCE_ROOT = {
1385                         name:           'Original Lisences',
1386                         type:           pettanr.file.FILE_TYPE.FOLDER,
1387                         children:       []
1388                 },
1389                 FILE_DATA_BALLOON_ROOT = {
1390                         name:           'Balloon templetes',
1391                         type:           pettanr.file.FILE_TYPE.FOLDER,
1392                         children:       []
1393                 },
1394                 AUTHOR_ARRAY = [],
1395                 ARTIST_ARRAY = [],
1396                 PANEL_ARRAY = [],
1397                 COMIC_ARRAY = [],
1398                 RESOURCE_PICTURE_ARRAY = [],
1399                 BALLOON_TEMPLETE_ARRAY = [],
1400                 ORIGINAL_LICENSE_ARRAY = [],
1401                 BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ',');
1402         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);
1403         FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_LATEST_COMICS, FILE_DATA_AUTHOR_ROOT);
1404         FILE_DATA_PICTURE_ROOT.children.push( FILE_DATA_MY_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT);
1405         
1406         FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT);
1407
1408         function onLoadJson( _file, _json ){
1409                 var _access = FileAPI.getFileDataAccess( _file),
1410                         _data = _access !== null ? _access.DATA : null,
1411                         l;
1412                 if( _data === null){
1413                         onErrorJson( _file);
1414                         return;
1415                 }
1416                 _data.state = pettanr.file.FILE_STATE.OK;
1417                 
1418                 if( Type.isArray( _json ) === true ){
1419                         l = _json.length;
1420                         if( l === 0) return;
1421                         for( var i=0; i<l; ++i ){
1422                                 buildFileData( _json[ i], _data);
1423                         }                       
1424                 } else
1425                 if( _json.id ){
1426                         buildFileData( _json, _data );
1427                 }
1428                 _access.dispatchFileEvent( FileAPI.createFileEvent( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, _file, 'children', null));
1429         }
1430         function onErrorJson( _file ){ 
1431                 var _data = FileAPI.getFileData( _file);
1432                 if( _data !== null){
1433                         _data.state = pettanr.file.FILE_STATE.ERROR;
1434                 }
1435         }
1436         function buildFileData( _data, _parent ){
1437                 var _array, i, l;
1438                 // Panel
1439                 if( _parent === FILE_DATA_PANELS_ROOT ){
1440                         _data.type = pettanr.driver.FILE_TYPE.PANEL;
1441                         _array = PANEL_ARRAY;
1442                 } else
1443                 // Comic
1444                 if( _parent === FILE_DATA_COMICS_ROOT ){
1445                         _data.type = pettanr.driver.FILE_TYPE.COMIC;
1446                         _array = COMIC_ARRAY;
1447                 } else
1448                 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC ){
1449                         _array = COMIC_ARRAY;
1450                 } else
1451                 // Lisence
1452                 if( _parent === FILE_DATA_LISENCE_ROOT ){
1453                         _data.type = pettanr.driver.FILE_TYPE.LICENSE;
1454                         _array = ORIGINAL_LICENSE_ARRAY;
1455                 } else
1456                 // Author
1457                 if( _parent === FILE_DATA_AUTHOR_ROOT ){
1458                         _data.type = pettanr.driver.FILE_TYPE.AUTHOR;
1459                         _array = AUTHOR_ARRAY;
1460                 } else
1461                 // Artist
1462                 if( _parent === FILE_DATA_ARTIST_ROOT ){
1463                         _data.type = pettanr.driver.FILE_TYPE.ARTIST;
1464                         _array = ARTIST_ARRAY;
1465                 } else          
1466                 // Picture
1467                 if( _parent === FILE_DATA_PICTURE_ROOT || _parent === FILE_DATA_MY_PICTURES_ROOT ){
1468                         _data.type = pettanr.driver.FILE_TYPE.PICTURE;
1469                         _array = RESOURCE_PICTURE_ARRAY;
1470                         // original_license を含まなければ、license object を削除して ビットデータ で保持
1471                         // original_license なら ファイルを作る buildFileData( _license, FILE_DATA_LISENCE_ROOT)
1472                         var _license = _data.license,
1473                                 _rule,
1474                                 _Math_pow = Math.pow,
1475                                 _bits = 0;
1476                         if( typeof _license === 'object'){
1477                                 for( i=0, l=BASIC_LICENSES.length; i<l; ++i){
1478                                         _rule = _license[ BASIC_LICENSES[ i]]
1479                                         if( typeof _rule === 'number' && _rule === 1 ){
1480                                                 _bits += _Math_pow( 2, i);
1481                                         }
1482                                 }
1483                                 _data.license = _bits;
1484                         }
1485                 } else {
1486                         alert( 'error' );
1487                 }
1488                 
1489                 _data.driver = Driver;
1490                 
1491                 // _array に _data を格納 または 上書き
1492                 if( typeof _data.id === 'number' && _data.id > 0 ){
1493                         var _id = _data.id - 1,
1494                                 __data = _array[ _id ],
1495                                 _reserved = pettanr.file.FILE_DATA_PROPERTY_RESERVED.join( ', ' );
1496                         if( __data ){
1497                                 for( var key in _data){
1498                                         if( _reserved.indexOf( key ) === -1 ){
1499                                                 __data[ key ] = _data[ key ];
1500                                         }
1501                                 }
1502                                 _data = __data; // このタイミングで参照が切れるので注意!!
1503                         } else {
1504                                 _array[ _id ] = _data;
1505                         }
1506                 } else {
1507                         alert( 'error' );
1508                 }
1509
1510                 // Author
1511                 // Artist
1512                 if( _parent === FILE_DATA_AUTHOR_ROOT || _parent === FILE_DATA_ARTIST_ROOT ){
1513                         addChildData( _parent, _data );
1514                 } else
1515                 // Comic + Panels
1516                 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC || _parent === FILE_DATA_COMICS_ROOT ){
1517                         var _panels = _data.panels,
1518                                 _panel;
1519                         if( _panels && Type.isArray( _panels ) === true ){
1520                                 
1521                                 for( i=0, l=_panels.length; i<l; ++i){
1522                                         _panel = buildFileData( _panels[ i ], FILE_DATA_PANELS_ROOT );
1523                                         /*
1524                                          * 間違い! t 順に格納
1525                                          */
1526                                         addChildData( _data, _panel );
1527                                 }
1528                                 delete _data.panels;
1529                         } else {
1530                                 if( _data.json !== null ){
1531                                         _data.json = true;
1532                                 }
1533                                 if( Type.isArray( _data.children ) === false ){
1534                                         _data.children = [];
1535                                 }                               
1536                         }
1537                         var _author = _data.author || getResource( AUTHOR_ARRAY, _data.author_id );
1538                         if( _author ){
1539                                 _data.author = _author = buildFileData( _author, FILE_DATA_AUTHOR_ROOT );
1540                                 addChildData( _author, _data );
1541                                 _author.id === MyAuthorID && addChildData( FILE_DATA_MY_COMICS_ROOT, _data );
1542                         }
1543                         if( _parent === FILE_DATA_COMICS_ROOT ){
1544                                 addChildData( FILE_DATA_LATEST_COMICS, _data);
1545                         }
1546                 } else
1547                 // Panel
1548                 if( _parent === FILE_DATA_PANELS_ROOT ){
1549                         _data.comic = getResource( COMIC_ARRAY, _data.comic_id );
1550                         _data.author = getResource( AUTHOR_ARRAY, _data.author_id );
1551
1552                         // picture data をファイルに取り出し
1553                         var _elements = _data.panel_elements,
1554                                 _elm;
1555                         if( Type.isArray( _elements ) === true ){
1556                                 for( i=0, l=_elements.length; i<l; ++i){
1557                                         _elm = _elements[ i];
1558                                         if( _elm.resource_picture ){
1559                                                 _elm.resource_picture = buildFileData( _elm.resource_picture, FILE_DATA_PICTURE_ROOT ); // 上記参照切れに備えてここで上書き
1560                                         } else {
1561                                                 _elm.resource_picture = getResource( RESOURCE_PICTURE_ARRAY, _elm.resource_picture_id );
1562                                         }
1563                                 }                               
1564                         }
1565                 } else
1566                 // Picture
1567                 if( _data.type == pettanr.driver.FILE_TYPE.PICTURE ){
1568                         var _artist = _data.artist || getResource( ARTIST_ARRAY, _data.artist_id );
1569                         if( _artist){
1570                                 _data.artist = _artist = buildFileData( _artist, FILE_DATA_ARTIST_ROOT );
1571                                 addChildData( _artist, _data );
1572                                 if( _artist.id === MyArtistID ){
1573                                         addChildData( FILE_DATA_MY_PICTURES_ROOT, _data );
1574                                         //FILE_DATA_MY_PICTURES_ROOT.type = pettanr.driver.FILE_TYPE.ARTIST;
1575                                         //FILE_DATA_MY_PICTURES_ROOT.id = MyArtistID;
1576                                 }
1577                         }
1578                 }
1579                 return _data;
1580         }
1581         function addChildData( _parent, _child ){
1582                 if( Type.isArray( _parent.children ) === false){
1583                         _parent.children = [];
1584                 }
1585                 pettanr.util.getIndex( _parent.children, _child ) === -1 && _parent.children.push( _child );
1586         }
1587         function getResource( _array, _id ){
1588                 if( Type.isArray( _array ) === false || Type.isNumber( _id ) === false || _id < 1 ) return null;
1589                 var _data = _array[ _id - 1 ];
1590                 if( !_data ){
1591                         _data = _array[ _id - 1 ] = {};
1592                 }
1593                 return _data;
1594         }
1595
1596         return {
1597                 createComicTree: function(){
1598                         return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT ); //FILE_DATA_COMICS_ROOT);
1599                 },
1600                 createPictureTree: function(){
1601                         var _tree  = pettanr.file.createTree( FILE_DATA_PICTURE_ROOT );
1602                                 _root  = _tree.getRootFile();
1603                                 _myPic = _root.getChildFileByIndex( 0 );
1604                                 _pic   = _root.getChildFileByIndex( 1 );
1605                         _myPic.getSeqentialFiles();
1606                         _pic.getSeqentialFiles();
1607                         _myPic.destroy();
1608                         _pic.destroy();
1609                         return _tree;
1610                 },
1611                 createArtistTree: function(){
1612                         return pettanr.file.createTree( FILE_DATA_ARTIST_ROOT );
1613                 },
1614                 createServiceTree: function(){
1615                         return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT );
1616                 },
1617                 isPettanrFileInstance: function( _file ){
1618                         if( pettanr.file.isFileInstance( _file ) === true){
1619                                 var _data = FileAPI.getFileData( _file);
1620                                 return _data !== null && _data.driver === Driver;
1621                         }
1622                         return false;
1623                 },
1624                 _getAPI: function(){
1625                         return FileAPI;
1626                 },
1627                 _getPictureRootData: function(){
1628                         return FILE_DATA_PICTURE_ROOT;
1629                 },
1630                 _getMyPicturesData: function(){
1631                         return FILE_DATA_MY_PICTURES_ROOT;
1632                 },
1633                 FILE_TYPE: {
1634                         COMIC:                          FileAPI.createFileTypeID(),
1635                         PANEL:                          FileAPI.createFileTypeID(),
1636                         PICTURE:                        FileAPI.createFileTypeID(),
1637                         PANEL_PICTURE:          FileAPI.createFileTypeID(),
1638                         BALLOON:                        FileAPI.createFileTypeID(),
1639                         AUTHOR:                         FileAPI.createFileTypeID(),
1640                         ARTIST:                         FileAPI.createFileTypeID(),
1641                         LICENSE:                        FileAPI.createFileTypeID()
1642                 }
1643         }
1644 })();
1645
1646 pettanr.entrance = pettanr.view.registerApplication( function(){
1647         var wrap = document.getElementById('inner-wrapper'),
1648                 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height,
1649                 instance = this;
1650         this.displayName = 'Home';
1651         this.ID          = 'Home';
1652         this.rootElement = document.getElementById('entrance');
1653         this.onOpen = function( _w, _h, _option ){
1654                 wrap.style.display = '';
1655                 wrap.style.height = ( _h - pageHeaderH ) + 'px';
1656         }
1657         this.onClose = function(){
1658                 wrap.style.display = 'none';
1659         }
1660         this.onPaneResize = function( _w, _h){
1661                 instance.onOpen( _w, _h );
1662         }
1663 });
1664 pettanr.entrance.addToLancher();
1665
1666 pettanr.cabinet = pettanr.view.registerApplication( function(){
1667         var finder,
1668                 elmContainer = document.getElementById( 'cabinet'),
1669                 option,
1670                 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height;
1671                 
1672         this.displayName = 'Comic list';
1673         this.ID          = 'Comiclist';
1674         this.rootElement = elmContainer;
1675         this.onOpen = function( _w, _h ){
1676                 finder = finder || pettanr.finder.createFinder( pettanr.cabinet, elmContainer, pettanr.driver.createComicTree() );
1677                 finder.resize( _w, _h - pageHeaderH );
1678         }
1679         this.onClose = function(){
1680                 // finder.close();
1681         }
1682         this.onPaneResize = function( _w, _h){
1683                 finder.resize( _w, _h - pageHeaderH );
1684         }
1685 });
1686 pettanr.cabinet.addToLancher();
1687
1688 pettanr.gallery = pettanr.view.registerApplication( function(){
1689         var finder,
1690                 elmContainer = document.getElementById( 'gallery' ),
1691                 option,
1692                 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height;
1693                 
1694         this.displayName = 'Pictures';
1695         this.ID          = 'pictures';
1696         this.rootElement = elmContainer;
1697         this.onOpen = function( _w, _h ){
1698                 finder = finder || pettanr.finder.createFinder( pettanr.gallery, elmContainer, pettanr.driver.createPictureTree() );
1699                 finder.resize( _w, _h - pageHeaderH );
1700         }
1701         this.onClose = function(){
1702                 // finder.close();
1703         }
1704         this.onPaneResize = function( _w, _h){
1705                 finder.resize( _w, _h - pageHeaderH );
1706         }
1707 });
1708 pettanr.gallery.addToLancher();
1709
1710 pettanr.backyard = pettanr.view.registerApplication( function(){
1711         this.displayName = 'Settings';
1712         this.ID          = 'Settinds';
1713         this.rootElement = document.getElementById( 'backyard' );
1714         this.onOpen = function( _w, _h, _option ){
1715         }
1716         this.onClose = function(){
1717         }
1718         this.onPaneResize = function( _w, _h){
1719         }
1720 });
1721 pettanr.backyard.addToLancher();
1722
1723 if( pettanr.DEBUG === true){
1724         pettanr.debug = pettanr.view.registerApplication( function(){
1725                 var elmDl = document.getElementById( 'useragent'),
1726                         elmDt, elmDd,
1727                         data = {
1728                                 pettanR:        pettanr.version,
1729                                 ua:                     navigator.userAgent,
1730                                 platform:       navigator.platform,
1731                                 appVersion:     navigator.appVersion,
1732                                 appCodeName:navigator.appCodeName,
1733                                 appName:        navigator.appName,
1734                                 language:       navigator.browserLanguage || navigator.language,
1735                                 ActiveX:        pettanr.ua.ACTIVEX
1736                         },
1737                         ua = pettanr.ua;
1738                 if( ua.IE){
1739                         //data.ua = 'Internet Explorer';
1740                         data.version = ua.IE;
1741                         if( ua.ieVersion >= 8) data.RenderingVersion = ua.ieRenderingVersion;
1742                         data.browserType = ua.STANDALONE === true ? 'Standalone' : 'bundle';
1743                         if( ua.ieVersion < 9) {
1744                                 data.vml = ua.VML;
1745                         } else {
1746                                 data.svg = ua.SVG;
1747                         }
1748                 }
1749                 data.RenderingMode = ua.isStanderdMode === true ? 'Standerd' : 'Quirks';
1750                 
1751                 for( var key in data){
1752                         elmDt = document.createElement( 'dt');
1753                         elmDt.innerHTML = key;
1754                         elmDd = document.createElement( 'dd');
1755                         elmDd.innerHTML = '' + data[ key];
1756                         if( !data[ key]) elmDd.style.color = 'red';
1757                         elmDl.appendChild( elmDt);
1758                         elmDl.appendChild( elmDd);
1759                 }
1760                 
1761                 var wrap = document.getElementById('inner-wrapper'),
1762                         pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' )).height,
1763                         instance = this;
1764                 
1765                 this.displayName = 'Debug';
1766                 this.ID          = 'debug';
1767                 this.rootElement = document.getElementById( 'debug' );
1768                 this.onOpen = function( _w, _h, _option ){
1769                         wrap.style.display = '';
1770                         wrap.style.height = ( _h - pageHeaderH ) + 'px';
1771                 }
1772                 this.onClose = function(){
1773                         wrap.style.display = 'none';
1774                 }
1775                 this.onPaneResize = function( _w, _h ){
1776                         instance.onOpen( _w, _h );
1777                 }
1778         });
1779         pettanr.debug.addToLancher();
1780         
1781 } else {
1782         var _debug = document.getElementById( 'debug');
1783         if( _debug){
1784                 pettanr.util.removeAllChildren( _debug);
1785                 _debug.parentNode.removeChild( _debug);
1786                 _debug = null;
1787         }
1788 }
1789
1790 /* ----------------------------------------
1791  * Image Group Exproler
1792  *  - overlay
1793  */
1794 pettanr.premiumSatge = pettanr.view.registerApplication( function(){
1795         var ICON_ARRAY = [],
1796                 WHEEL_DELTA = 64,
1797                 ARTIST_TREE = pettanr.driver.createArtistTree(),
1798                 ARTIST_ROOT_FILE = ARTIST_TREE.getRootFile(),
1799                 instance = this,
1800                 winW, winH,
1801                 wrapX,
1802                 elmWrap = document.getElementById( 'image-group-wrapper' ),
1803                 elmContainer = document.getElementById( 'image-group-icon-container' ),
1804                 containerW,
1805                 containerH = pettanr.util.getElementSize( elmContainer ).height,                
1806                 elmIconOrigin = ( function(){
1807                         var ret = document.createElement( 'div' ),
1808                                 data = document.createElement( 'div' );
1809                         ret.appendChild( data );
1810                         ret.className = 'image-group-item';
1811                         data.className = 'image-group-item-title';
1812                         return ret;
1813                 })(),
1814                 jqContainer,
1815                 size = pettanr.util.getElementSize( elmIconOrigin ),
1816                 itemW = size.width,
1817                 itemH = size.height,
1818                 elmName = document.getElementById( 'image-group-name' ),
1819                 elmButton = document.getElementById( 'image-group-button' ),
1820                 buttonW = pettanr.util.getElementSize( elmButton ).width,
1821                 //onUpdateFunction,
1822                 onUpdateFunction = null,
1823                 onUpdateData = null,
1824                 artistID = -1,
1825                 onEnterInterval = null;
1826
1827         elmButton.onclick = clickOK;
1828         
1829         var BASE_PATH = pettanr.CONST.RESOURCE_PICTURE_PATH,
1830                 THUMB_PATH = BASE_PATH, // + 'thumbnail/',
1831                 LIMIT_FILESIZE = 1024 * 10; // 10KB
1832
1833         var ImageGroupIconClass = function( INDEX, data ){
1834                 var elmIconWrap     = elmIconOrigin.cloneNode( true ),
1835                         elmIconTitle    = pettanr.util.getElementsByClassName( elmIconWrap, 'image-group-item-title' )[ 0 ],
1836                         SRC             = [ BASE_PATH, data.id, '.', data.ext ].join( ''),
1837                         LOW_SRC         = data.filesize && data.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext ].join( '') : null,
1838                         reversibleImage = null,
1839                         timer           = null,
1840                         onEnterFlag     = false,
1841                         instance        = this;
1842                 elmContainer.appendChild( elmIconWrap );
1843                 elmIconWrap.style.left = ( INDEX * itemW ) + 'px';
1844                 elmIconTitle.appendChild( document.createTextNode( data.filesize + 'bytes' ) );
1845                 
1846                 function onImageLoad( url, _imgW, _imgH ){
1847                         data.width = _imgW = _imgW || data.width || 64;
1848                         data.height = _imgH = _imgH || data.height || 64;
1849                         elmIconTitle.firstChild.data = _imgW + 'x' + _imgH;
1850                         var zoom = 128 /( _imgW > _imgH ? _imgW : _imgH ),
1851                                 MATH_FLOOR = Math.floor,
1852                                 h = MATH_FLOOR( _imgH * zoom ),
1853                                 w = MATH_FLOOR( _imgW * zoom );
1854                         reversibleImage.elm.style.cssText = [
1855                                 'width:',  w, 'px;',
1856                                 'height:', h, 'px;',
1857                                 'margin:', MATH_FLOOR( itemH / 2 - h / 2 ), 'px ', MATH_FLOOR( itemW / 2 - w / 2 ), 'px 0'
1858                         ].join('');
1859                         reversibleImage.resize( w, h );
1860                         elmIconWrap.onclick = onClick;
1861                 }
1862                 
1863                 function onClick(){
1864                         onUpdateData = data;
1865                         pettanr.premiumSatge.shutdown();
1866                 }
1867                 
1868                 function asyncDraw(){
1869                         reversibleImage = pettanr.image.createReversibleImage( LOW_SRC || SRC, itemW, itemH, onImageLoad );
1870                         elmIconWrap.appendChild( reversibleImage.elm );
1871                         onEnterFlag = true;
1872                         timer = null;
1873                 }
1874                 
1875                 this.onEnter = function( delay ){
1876                         timer = window.setTimeout( asyncDraw, delay );
1877                         delete instance.onEnter;
1878                 }
1879                 this.destroy = function(){
1880                         delete instance.destroy;
1881                         timer && window.clearTimeout( timer );
1882                         reversibleImage && reversibleImage.destroy();
1883                         pettanr.util.removeAllChildren( elmIconWrap );
1884                         elmContainer.removeChild( elmIconWrap );
1885                         elmIconWrap.onclick = '';
1886                         reversibleImage = elmIconWrap = elmIconTitle = data = timer = null;
1887                 }
1888         }
1889         
1890         function onEnterShowImage(){
1891                 var l = ICON_ARRAY.length,
1892                         _start = -wrapX /itemW -1,
1893                         _end = _start + winW /itemW +1,
1894                         _icon;
1895                 for( var i=0, c = 0; i<l; ++i){
1896                         _icon = ICON_ARRAY[ i ];
1897                         if( _start < i && i < _end && _icon.onEnter ){
1898                                 _icon.onEnter( c * 100 );
1899                                 c++;
1900                         }
1901                 }
1902                 onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1903                 onEnterInterval = null;
1904         }
1905         function clickOK(){
1906                 pettanr.premiumSatge.shutdown();
1907         }
1908         function onMouseWheel( e, delta ){
1909                 if( winW < containerW){
1910                         wrapX += delta * WHEEL_DELTA;
1911                         wrapX = wrapX > 0 ? 0 : wrapX < winW -containerW ? winW -containerW : wrapX;
1912                         jqContainer.css( { left: wrapX});
1913                         
1914                         onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1915                         onEnterInterval = window.setTimeout( onEnterShowImage, 500 );
1916                 }
1917                 //e.stopPropagation();
1918                 return false;                   
1919         }
1920         
1921         function drawIcons(){
1922                 while( ICON_ARRAY.length > 0 ){
1923                         ICON_ARRAY.shift().destroy();
1924                 }
1925                 
1926                 var _index = ARTIST_ROOT_FILE.search( {
1927                                 id:   artistID,
1928                                 type: pettanr.driver.FILE_TYPE.ARTIST
1929                         })[ 0 ],
1930                         _artistFile = ARTIST_ROOT_FILE.getChildFileByIndex( _index ),
1931                         _file;
1932                 if( _artistFile !== null ){
1933                         for(var i=0, l=_artistFile.getChildFileLength(); i<l; ++i ){
1934                                 _file = _artistFile.getChildFileByIndex( i );
1935                                 ICON_ARRAY.push( new ImageGroupIconClass( i, pettanr.driver._getAPI().getFileData( _file ) ));
1936                                 _file.destroy();
1937                         }
1938                         elmName.firstChild.data = _artistFile.getName();
1939                         _artistFile.destroy();
1940                 }
1941         }
1942         
1943         function onFadeout(){
1944                 while( ICON_ARRAY.length > 0 ){
1945                         ICON_ARRAY.shift().destroy();
1946                 }
1947                 onUpdateFunction !== null && onUpdateData !== null && onUpdateFunction( onUpdateData );
1948                 onUpdateFunction = onUpdateData = null;
1949         }
1950         
1951         /* grobal method */
1952         // this.rootElement = elmWrap;
1953         this.displayName = 'premiumStage';
1954         this.ID          = 'premiumStage';
1955         this.rootElement = elmWrap;
1956         this.MIN_WIDTH   = 320;
1957         this.MIN_HEIGHT  = 320;
1958         this.init = function(){
1959                 jqContainer = $( elmContainer ).mousewheel( onMouseWheel );
1960                 
1961                 // よくない! 一時的な処理,,,
1962                 //var tree = pettanr.driver.createPictureTree();
1963                 //tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, drawIcons );
1964                 // pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES
1965                 delete instance.init;
1966         }
1967         this.onOpen = function( _windowW, _windowH, _ARTISTIDorFILE, _onUpdateFunction ){
1968                 instance.init && instance.init();
1969                 
1970                 if( pettanr.driver.isPettanrFileInstance( _ARTISTIDorFILE ) === true ){
1971                         var _data = pettanr.driver._getAPI().getFileData( _ARTISTIDorFILE );
1972                         if( _ARTISTIDorFILE.getType() === pettanr.driver.FILE_TYPE.ARTIST || pettanr.driver._getMyPicturesData() === _data ){
1973                                 artistID = _data.id || -1;
1974                         }
1975                 } else
1976                 if( Type.isNumber( _ARTISTIDorFILE ) === true ){
1977                         artistID = _ARTISTIDorFILE;
1978                 }
1979                 
1980                 onUpdateFunction = _onUpdateFunction || null;
1981                 onUpdateData = null;
1982                 
1983                 drawIcons();
1984                 
1985                 wrapX = 0;
1986                 containerW = ICON_ARRAY.length * itemW;
1987                 
1988                 winW = _windowW;
1989                 winH = _windowH;
1990                 var w = winW > containerW ? winW : containerW,
1991                         h = _windowH > containerH ? containerH : _windowH,
1992                         MATH_FLOOR = Math.floor;
1993                 
1994                 jqContainer.css( {
1995                         width:          w,
1996                         height:         0,
1997                         left:           0,
1998                         top:            MATH_FLOOR( _windowH /2)
1999                 }).stop().animate( {
2000                         height:         h,
2001                         top:            MATH_FLOOR( _windowH /2 -h /2)
2002                 }, onEnterShowImage );
2003                 
2004                 elmButton.style.cssText = [
2005                         'left:', MATH_FLOOR( winW /2 - buttonW /2), 'px;',
2006                         'top:', MATH_FLOOR( _windowH /2 + containerH /2 +10), 'px'
2007                 ].join('');
2008         }
2009         this.onPaneResize = function( _windowW, _windowH ){
2010                 var w = _windowW > containerW ? _windowW : containerW,
2011                         h = _windowH > containerH ? containerH : _windowH,
2012                         MATH_FLOOR = Math.floor,
2013                         offsetW = MATH_FLOOR( _windowW /2 -winW /2);
2014                         
2015                 winW = _windowW;
2016                 winH = _windowH;
2017                 if( offsetW <= 0){ // smaller
2018                         jqContainer.css( {
2019                                 left:                           offsetW,
2020                                 width:                          w
2021                         }).animate( {
2022                                 left:                           0,
2023                                 top:                            MATH_FLOOR( _windowH /2 -h /2)
2024                         });                                     
2025                 } else {
2026                         jqContainer.css( { // bigger
2027                                 left:                           0,
2028                                 width:                          w,
2029                                 borderLeftWidth:        offsetW
2030                         }).animate( {
2031                                 top:                            MATH_FLOOR( _windowH /2 -h /2),
2032                                 borderLeftWidth:        0
2033                         });
2034                 }
2035                 elmButton.style.cssText = [
2036                         'left:', MATH_FLOOR( _windowW /2 -buttonW /2), 'px;',
2037                         'top:', MATH_FLOOR( _windowH /2 +containerH /2 +10), 'px'
2038                 ].join('');
2039                 onEnterShowImage();
2040         }
2041         this.onClose = function(){
2042                 jqContainer.stop().animate( {
2043                                 height: 0,
2044                                 top:    Math.floor( winH /2 )
2045                         }, onFadeout );
2046                 onEnterInterval !== null && window.clearTimeout( onEnterInterval );
2047                 onEnterInterval = null;
2048         }
2049 });
2050
2051
2052 /* ----------------------------------------
2053  * Text Editor
2054  *  - overlay
2055  */
2056 pettanr.textEditor = pettanr.view.registerApplication( function(){
2057         var jqWrap, jqTextarea, jqButton,
2058                 textElement, onUpdateFunction,
2059                 ID = 'textEditor',
2060                 panelX, panelY,
2061                 instance = this;
2062         //pettanr.key.addKeyDownEvent( ID, 69, false, false, clickOK);
2063         
2064         function clickOK(){
2065                 textElement && textElement.text( jqTextarea.val() );
2066                 window.setTimeout( asyncCallback, 0 );
2067         }
2068         
2069         function asyncCallback(){
2070                 onUpdateFunction && onUpdateFunction( textElement );
2071                 onUpdateFunction = textElement = null;
2072                 pettanr.textEditor.shutdown();
2073         }
2074         
2075         function keyCancel( e ){
2076                 if( e.keyCode === 69 && e.shiftKey === false && e.ctrlKey === true){
2077                         clickOK();
2078                         e.preventDefault();
2079                 e.keyCode = 0;
2080                 e.cancelBubble = true;
2081                 e.returnValue = false;
2082                         return false;
2083                 }       
2084         }
2085         function textareaFitHeight(){
2086                 var rows = 0;
2087                 while( jqTextarea.height() < textElement.h ){
2088                         rows++;
2089                         jqTextarea.attr( 'rows', rows );
2090                 }
2091                 rows > 1 && jqTextarea.attr( 'rows', --rows );
2092         }
2093         
2094         /* grobal method */
2095         // this.rootElement = elmWrap;
2096         this.displayName = 'textEditor';
2097         this.ID          = 'textEditor';
2098         this.rootElement = document.getElementById( 'speach-editor-wrapper' );
2099         this.MIN_WIDTH   = 320;
2100         this.MIN_HEIGHT  = 320;
2101         this.init = function(){
2102                 jqWrap     = $( '#speach-editor-wrapper' ).hide();
2103                 jqTextarea = $( '#speach-editor' ).keydown( keyCancel );
2104                 jqButton   = $( '#speach-edit-complete-button').click( clickOK );
2105                 delete instance.init;
2106         }
2107         this.onOpen = function( _w, _h, _panelX, _panelY, _textElement, _onUpdateFunction ){
2108                 instance.init && instance.init();
2109                 
2110                 panelX = _panelX;
2111                 panelY = _panelY;
2112                 textElement = _textElement;
2113                 onUpdateFunction = _onUpdateFunction || null;
2114                 
2115                 jqWrap.show();
2116                 instance.onPaneResize( _w, _h );
2117                 jqTextarea.val( _textElement.text() ).focus();
2118                 
2119                 /*
2120                  * ie6,7は、textarea { width:100%}でも高さが変わらない。rowsを設定。
2121                  */
2122                 pettanr.ua.isIE === true && pettanr.ua.ieVersion <= 7 && setTimeout( textareaFitHeight, 0);
2123         }
2124         this.onPaneResize = function( _w, _h ){
2125                 jqWrap.css( {
2126                         left:                   textElement.x + panelX,
2127                         top:                    textElement.y + panelY,
2128                         width:                  textElement.w,
2129                         height:                 textElement.h
2130                 });
2131         }
2132         this.onClose = function(){
2133                 jqWrap.hide();
2134         }
2135 });
2136
2137
2138 pettanr.reader = pettanr.view.registerApplication( function(){
2139         var jqWrap, jqPanelContainer,
2140                 windowW, windowH,
2141                 headerH       = pettanr.util.getElementSize( document.getElementById( 'comic-reader-header' ) ).height,
2142                 consoleH      = pettanr.util.getElementSize( document.getElementById( 'comic-reader-console' ) ).height,
2143                 panelMargin,
2144                 elmContainer  = document.getElementById( 'comic-reader-panel-container' ),
2145                 elmTitle      = document.getElementById( 'comic-reader-title' ).firstChild,
2146                 elmAuthor     = document.getElementById( 'comic-reader-author' ).firstChild,
2147                 elmBackButton = document.getElementById( 'comic-reader-back-button' ),
2148                 elmNextButton = document.getElementById( 'comic-reader-forward-button' ),
2149                 ID            = 'comicReader',
2150                 bindWorker    = null,
2151                 currentFile   = null;
2152                 comicData     = null,
2153                 currentPanel  = null,
2154                 currentIndex  = 0,
2155                 numPanel      = 0,
2156                 instance      = this;
2157
2158         function onBackClick(){
2159                 currentIndex -= ( currentIndex > 0 ? 1 : 0 );
2160                 slide();
2161                 return false;
2162         }
2163         function onNextClick(){
2164                 currentIndex += ( currentIndex < numPanel - 1 ? 1 : 0 );
2165                 slide();
2166                 return false;
2167         }
2168         function slide(){
2169                 var elm    = elmContainer.childNodes[ currentIndex ],
2170                         h      = windowH - headerH - consoleH,
2171                         top    = headerH;
2172                 if( elm ){
2173                         top =  headerH - elm.offsetTop + Math.floor( ( h - elm.offsetHeight ) / 2 );
2174                 }
2175                 
2176                 jqPanelContainer.stop().animate( {
2177                         top:    top
2178                 });
2179         }
2180         function getCurrentTopPosition(){
2181
2182         }
2183         function draw(){
2184                 var fileData, title, author;
2185                 
2186                 if( pettanr.driver.isPettanrFileInstance( currentFile ) === true ){
2187                         if( currentFile.getType() === pettanr.driver.FILE_TYPE.COMIC ){
2188                                 fileData    = currentFile.read();
2189                                 title       = fileData.title;
2190                                 author      = fileData.author.name;
2191                                 comicData   = fileData;
2192                                 numPanel    = currentFile.getChildFileLength();
2193                         } else
2194                         if( currentFile.getType() === pettanr.driver.FILE_TYPE.PANEL ){
2195                                 fileData    = currentFile.read();
2196                                 title       = fileData.comic.title;
2197                                 author      = fileData.comic.author.name;
2198                                 comicData   = fileData;
2199                                 numPanel    = 1;
2200                         }
2201                 } else {
2202                         
2203                 }
2204
2205                 if( comicData !== null ){
2206                         elmTitle.data  = title;
2207                         elmAuthor.data = author;
2208                         bindWorker.json( comicData );
2209                         window.setTimeout( asyncResize, 0 );
2210                 }
2211         }
2212         function asyncResize(){
2213                 instance.onPaneResize( windowW, windowH );
2214         }
2215         
2216         /* grobal method */
2217         // this.rootElement = elmWrap;
2218         this.displayName = ID;
2219         this.ID          = ID;
2220         this.rootElement = document.getElementById( 'comic-reader-wrapper' );
2221         this.MIN_WIDTH   = 320;
2222         this.MIN_HEIGHT  = 320;
2223         this.init = function(){
2224                 jqWrap           = $( instance.rootElement );
2225                 jqPanelContainer = $( elmContainer );
2226                 
2227                 elmBackButton.onclick = onBackClick;
2228                 elmNextButton.onclick = onNextClick;
2229                 
2230                 bindWorker = pettanr.bind.createBindWorker( elmContainer, null, false, false );
2231                 
2232                 delete instance.init;
2233         }
2234         this.onOpen = function( _w, _h, _file ){
2235                 instance.init && instance.init();
2236                 numPanel = currentIndex = 0;
2237                 
2238                 jqWrap.show();
2239                 jqPanelContainer.css({
2240                         left:   _w / 2,
2241                         top:    _h
2242                 });
2243                 windowW = _w;
2244                 windowH = _h;
2245                 if( pettanr.file.isFileInstance( _file ) === true ){
2246                         currentFile = _file;
2247                         _file.addEventListener( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, draw );
2248                         draw();
2249                 }
2250         }
2251         this.onPaneResize = function( _windowW, _windowH ){
2252                 windowW = _windowW;
2253                 windowH = _windowH;
2254                 var panelH = elmContainer.offsetHeight,
2255                         panelW = elmContainer.offsetWidth,
2256                         h      = _windowH - headerH - consoleH;
2257                 jqPanelContainer.stop().animate(
2258                         {
2259                                 left:   Math.floor( ( _windowW - panelW ) / 2 ),
2260                                 top:    headerH + ( panelH < h ? Math.floor( ( h - panelH ) / 2 ) : 0 )
2261                         }
2262                 );
2263         }
2264         this.onClose = function(){
2265                 jqWrap.hide();
2266                 currentFile.addEventListener( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, draw );
2267                 currentFile = comicData = currentPanel = null;
2268         }
2269 });
2270
2271 // i18n
2272 // login
2273 // lib
2274
2275 pettanr.fn( pettanr.view);
2276 pettanr.fn( pettanr.overlay);
2277 pettanr.fn( pettanr.key);
2278 pettanr.fn( pettanr.balloon);
2279
2280 pettanr.fn( pettanr.editor);
2281
2282 pettanr.fn( pettanr.file);
2283 pettanr.fn( pettanr.finder);
2284 pettanr.fn( pettanr.gallery);
2285 pettanr.fn( pettanr.cabinet);
2286
2287 $(window).ready( pettanr.init);