OSDN Git Service

client is version0.4.27, added timer for appendChild, but still clash at ie7-.
[pettanr/pettanr.git] / public / assets / system.js
1 /*
2  * pettanR system.js
3  *   version 0.4.27
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                         this.callBack = _callback = null;
342                 }
343         }
344         
345         var FileEventClass = function( eventType, file, key, value){
346                 this.eventType = eventType;
347                 this.targetFile = file;
348                 this.updatedAttribute = key;
349                 this.updatedValue = value;
350         }
351
352 /*
353  * fileのdataはobjectで保持している。
354  * pettanr.file.の外からファイルをみるときは、FileClassを通して操作する。
355  * fileの変更、それに付随して追加されたイベントは、TreeClassで管理される。
356  * treeがdestryされると、fileのイベントリスナーも全て削除される。
357  * 他の tree も data の共通する currentFile に対してのみは、file の変更イベントを受け取って流す.
358  * 
359  * parentData のほうがいい!
360  */
361         
362         var FileClass = function( tree, parentData, data ){
363                 var uid = FILE_CONTROLER.getFileUID( data ),
364                         instance = this;
365                 
366                 FILEDATA_ACCESS.push(
367                         {
368                                 TREE:                           tree,
369                                 parentData:                     parentData,
370                                 DATA:                           data,
371                                 dispatchFileEvent:      dispatchEvent
372                         }
373                 );
374                 
375                 tree = parentData = data = null;
376                 
377                 function dispatchEvent( e ){
378                         FILE_CONTROLER.fileEventRellay( uid, e );
379                 }
380                 this.getUID = function(){
381                         return uid;
382                 }
383         };
384         
385         FileClass.prototype = {
386                 isChildFile: function( _FILEorFILEDATA){
387                         return this.getChildFileIndex( _FILEorFILEDATA) !== -1;
388                 },
389                 getSeqentialFiles: function(){
390                         var _driver = FILE_CONTROLER.getDriver( this );
391                         if( _driver !== null && typeof _driver.getSeqentialFiles === 'function' ){
392                                 _driver.getSeqentialFiles( this );
393                         }
394                 },
395                 addEventListener: function( _eventType, _callback ){
396                         FILE_CONTROLER.addEventListener( this, _eventType, _callback );
397                 },
398                 removeEventListener: function( _eventType, _callback ){
399                         FILE_CONTROLER.removeEventListener( this, _eventType, _callback );
400                 },
401                 getChildFileLength: function(){
402                         var children = FILE_CONTROLER.getChildren( this );
403                         return Type.isArray( children ) === true ? children.length : -1;
404                 },
405                 getChildFileIndex: function( _FILEorFILEDATA ){
406                         var children = FILE_CONTROLER.getChildren( this);
407                         if( Type.isArray( children ) === false ) return -1;
408                         var l = children.length,
409                                 _fileData = FILE_CONTROLER.getFileData( _FILEorFILEDATA );
410                         if( _fileData === null ) return -1;
411                         for( var i=0; i<l; ++i ){
412                                 if( children[ i ] === _fileData ) return i;
413                         }
414                         return -1;
415                 },
416                 getChildFileByIndex: function( _index ){
417                         var _access = FILE_CONTROLER.getFileDataAccess( this ),
418                                 _children = FILE_CONTROLER.getChildren( this );
419                         if( typeof _index !== 'number' || _index < 0 || Type.isArray( _children ) === false || _index >= _children.length) return null;
420                         var _file = new FileClass( _access.TREE, _access.DATA, _children[ _index ]);
421                         // _file.init();
422                         return _file;
423                 },
424                 getName: function(){
425                         var driver = FILE_CONTROLER.getDriver( this );
426                         if( typeof driver.getName === 'function'){
427                                 return driver.getName( this );
428                         }
429                         return FileDriverBase.getName( this);
430                 },
431                 getThumbnail: function(){
432                         var driver = FILE_CONTROLER.getDriver( this);
433                         if( typeof driver.getThumbnail === 'function'){
434                                 return driver.getThumbnail( this);
435                         }
436                         return FileDriverBase.getThumbnail( this);
437                 },
438                 getType: function(){
439                         var _data = FILE_CONTROLER.getFileData( this);
440                         return typeof _data.type === 'number' ? _data.type : pettanr.file.FILE_TYPE.UNKNOWN;
441                 },
442                 getState: function(){
443                         var _data = FILE_CONTROLER.getFileData( this);
444                         return typeof _data.state === 'number' ? _data.state : pettanr.file.FILE_STATE.OK;
445                 },
446                 getSummary: function(){
447                         var driver = FILE_CONTROLER.getDriver( this );
448                         if( typeof driver.getSummary === 'function'){
449                                 return driver.getSummary( this );
450                         }
451                         return FileDriverBase.getSummary( this);
452                 },
453                 isWritable: function(){
454                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.WRITE );
455                 },
456                 isSortable: function(){
457                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.SORT );
458                 },              
459                 isCreatable: function(){
460                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.CREATE );
461                 },
462                 isRenamable: function(){
463                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.RENAME );
464                 },
465                 isDeletable: function(){
466                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.DELETE );
467                 },
468                 read: function(){
469                         // simpleDeepCopy
470                         var driver = FILE_CONTROLER.getDriver( this );
471                         if( typeof driver.read === 'function'){
472                                 return driver.read( this );
473                         }
474                         return FileDriverBase.read( this );
475                 },
476                 write: function( _newData, _onUpdateFunction ){
477                         var driver = FILE_CONTROLER.getDriver( this );
478                         if( typeof driver.write === 'function'){
479                                 return driver.write( this, _newData, _onUpdateFunction );
480                         }
481                         return FileDriverBase.write( this, _newData, _onUpdateFunction );
482                 },
483                 viewerApplicationList: function(){
484                         var driver = FILE_CONTROLER.getDriver( this );
485                         if( typeof driver.viewerApplicationList === 'function'){
486                                 return driver.viewerApplicationList( this );
487                         }
488                         return FileDriverBase.viewerApplicationList( this );
489                 },
490                 editorApplicationList: function(){
491                         var driver = FILE_CONTROLER.getDriver( this );
492                         if( typeof driver.editorApplicationList === 'function'){
493                                 return driver.editorApplicationList( this );
494                         }
495                         return FileDriverBase.viwerApps( this );
496                 },
497                 create: function(){
498                         
499                 },
500                 sort: function(){
501                         
502                 },
503                 onCopy: function(){
504                         
505                 },
506                 onDelete: function(){
507                         
508                 },
509                 move: function( _newFolder, _newIndex, opt_callback ){
510                         var _access = FILE_CONTROLER.getFileDataAccess( this );
511                         _access.TREE.move( _access.parentData, this.getUID(), _newFolder, _newIndex, opt_callback );
512                 },
513                 replace: function( _newIndex, opt_callback ){
514                         var _access = FILE_CONTROLER.getFileDataAccess( this );
515                         _access.TREE.replace( _access.parentData, this.getUID(), _newIndex, opt_callback);
516                 },
517                 /**
518                  * サーチ
519                  * 探しているファイルの属性と値を指定.一致する child の index を配列で返す.
520                  */
521                 search: function( obj, rule ){
522                         var _children = FILE_CONTROLER.getChildren( this ),
523                                 _child,
524                                 ret = [], k, c;
525                         for( var i=0, l=_children.length; i<l; ++i ){
526                                 _child = _children[ i ];
527                                 c = true;
528                                 for( k in obj ){
529                                         if( obj[ k ] !== _child[ k ] ){
530                                                 c = false;
531                                                 break;
532                                         }
533                                 }
534                                 c === true && ret.push( i );
535                         }
536                         return ret;
537                 },
538                 destroy: function(){
539                         var _access = FILE_CONTROLER.getFileDataAccess( this );
540                         var TREE = _access.TREE;
541                         if( TREE.getCurrentFile() === this ) return;
542                         if( TREE.getRootFile() === this ) return;
543                         for( var i=0, l = TREE.hierarchy(); i<l; ++i ){
544                                 if( TREE.getParentFileAt( i ) === this ){
545                                         return;
546                                 }
547                         }
548                         var _index = pettanr.util.getIndex( FILEDATA_ACCESS, _access );
549                         if( _index === -1 || _access === null ) return;
550                         // event の 削除
551                         FILEDATA_ACCESS.splice( _index, 1 );
552                         delete _access.DATA;
553                         delete _access.TREE;
554                         delete _access.parentData;
555                         delete _access.dispatchFileEvent;
556                 }
557         }
558
559         /*
560          * FileDriverBase
561          */
562         var FileDriverBase = {
563                 getSeqentialFiles: function( _file){
564                 },
565                 getName: function( _file){
566                         var _data = FILE_CONTROLER.getFileData( _file);
567                         return _data.name || 'No Name';
568                 },
569                 getThumbnail: function( _file){
570                         var _data = FILE_CONTROLER.getFileData( _file),
571                                 _type = _data.type,
572                                 _className = '';
573                         if( _type === pettanr.file.FILE_TYPE.FOLDER){
574                                 _className = 'folder';
575                         } else
576                         if( _type === pettanr.file.FILE_TYPE.IMAGE){
577                                 
578                         } else
579                         if( _type === pettanr.file.FILE_TYPE.TEXT){
580                                 
581                         } else
582                         if( _type === pettanr.file.FILE_TYPE.HTML){
583                                 
584                         } else
585                         if( _type === pettanr.file.FILE_TYPE.CSV){
586                                 
587                         } else
588                         if( _type === pettanr.file.FILE_TYPE.JSON){
589                                 
590                         } else
591                         if( _type === pettanr.file.FILE_TYPE.XML){
592                                 
593                         }
594                         return {
595                                 image:          null,
596                                 className:      ' file-type-' + _className
597                         }
598                 },
599                 getSummary: function( _file ){
600                         var _data = FILE_CONTROLER.getFileData( _file ),
601                                 _type = _data.type;
602                         if( _type === pettanr.file.FILE_TYPE.FOLDER){
603                                 return 'folder';
604                         } else
605                         if( _type === pettanr.file.FILE_TYPE.IMAGE){
606                                 return 'image file';
607                         } else
608                         if( _type === pettanr.file.FILE_TYPE.TEXT){
609                                 return 'text file';
610                         } else
611                         if( _type === pettanr.file.FILE_TYPE.HTML){
612                                 return 'html document file';
613                         } else
614                         if( _type === pettanr.file.FILE_TYPE.CSV){
615                                 return 'csv daat file';
616                         } else
617                         if( _type === pettanr.file.FILE_TYPE.JSON){
618                                 return 'json data file';
619                         } else
620                         if( _type === pettanr.file.FILE_TYPE.XML){
621                                 return 'xml data file';
622                         }
623                         return '';
624                 },
625                 getUpdatePolicy: function( _file ){
626                         // debug用 全てのメニューを許可
627                         return pettanr.file.FILE_UPDATE_POLICY.DSRWC;
628                 },
629                 read: function( _file ){
630                         var data = FILE_CONTROLER.getFileData( _file ),
631                                 protects = pettanr.file.FILE_DATA_PROPERTY_RESERVED;
632                         
633                         function clone( src ) {
634                                 var ret;
635                                 if( Type.isArray(src) === true ){
636                                         ret = [];
637                                 } else
638                                 if( Type.isObject(src) === true ){
639                                         ret = {};
640                                 } else
641                                 if( Type.isNumber(src) === true || Type.isString(src) === true || Type.isBoolean( src ) === true ){
642                                         return src;
643                                 } else {
644                                         return null;
645                                 }
646                                 for( var key in src ){
647                                         if( pettanr.util.getIndex( protects, key ) === -1 ){
648                                                 //alert( key )
649                                                 ret[ key ] = clone( src[ key ]);
650                                         }
651                                 }
652                                 return ret;
653                         };
654                                 
655                         return clone( data );
656                 },
657                 write: function( _file, _newData, _onUpdateFunction ){
658                         var _data = FILE_CONTROLER.getFileData( _file ),
659                                 _type = _data.type;
660                         return false;
661                 },
662                 viewerApplicationList: function(){
663                         return [];
664                 },
665                 editorApplicationList: function(){
666                         return [];
667                 },
668                 onCreate: function(){
669                         
670                 },
671                 onSort: function(){
672                         
673                 },
674                 onCopy: function(){
675                         
676                 },
677                 onDelete: function(){
678                         
679                 }
680         }
681
682         var ROOT_FILEDATA = {
683                         name:           'system root',
684                         type:           FILE_TYPE_IS_FOLDER,
685                         children:       []
686                 },
687                 SYSTEM_TREE = FILE_CONTROLER.createTree( ROOT_FILEDATA),
688                 ROOT_FILE = SYSTEM_TREE.getRootFile();
689         
690         function createFolderUnderRoot( _fileData){
691                 ROOT_FILEDATA.children.push( _fileData);
692                 FILE_CONTROLER.getFileDataAccess( ROOT_FILE)
693                         .dispatchFileEvent( new FileEventClass( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, ROOT_FILE, 'children', null));
694         }
695         function createFileEvent( _eventType, _file, _key, _value){
696                 return new FileEventClass( _eventType, _file, _key, _value);
697         }
698         function createFileTypeID(){
699                 return ++numFileType;
700         }
701         
702         return {
703                 init: function(){
704                         //REQUEST_CONTROLER.init();
705                         //FILE_CONTROLER.init();
706                         delete pettanr.file.init;
707                 },
708                 registerDriver: function( _driver ){
709                         _driver.prototype = FileDriverBase;
710                         /*
711                          * File API
712                          */
713                         return {
714                                 createFolderUnderRoot:  createFolderUnderRoot,
715                                 getFileDataAccess:              FILE_CONTROLER.getFileDataAccess,
716                                 getFileData:                    FILE_CONTROLER.getFileData,
717                                 getJson:                                REQUEST_CONTROLER.getJson,
718                                 createFileEvent:                createFileEvent,
719                                 createFileTypeID:               createFileTypeID
720                         }
721                 },
722                 createTree: function( _rootFile){
723                         return FILE_CONTROLER.createTree( _rootFile);
724                 },
725                 isTreeInstance: function( _tree){
726                         return _tree instanceof TreeClass;
727                 },
728                 isFileInstance: function( _file){
729                         return _file instanceof FileClass;
730                 },
731                 FILE_TYPE: {
732                         UNKNOWN:        0,
733                         FOLDER:         FILE_TYPE_IS_FOLDER,
734                         IMAGE:          createFileTypeID(),
735                         TEXT:           createFileTypeID(),
736                         HTML:           createFileTypeID(),
737                         CSV:            createFileTypeID(),
738                         JSON:           createFileTypeID(),
739                         XML:            createFileTypeID()
740                 },
741                 FILE_STATE: {
742                         UNKNOWN:        0,
743                         OK:                     1,
744                         LOADING:        2,
745                         ERROR:          3,
746                         BROKEN:         4
747                 },
748                 FILE_UPDATE_POLICY: {
749                         _____:          parseInt( '00000', 2),
750                         ____C:          parseInt( '00001', 2), // hasCreateMenu
751                         ___W_:          parseInt( '00010', 2), // isWritable
752                         ___WC:          parseInt( '00011', 2), // isWritable
753                         __R__:          parseInt( '00100', 2), // isRenamable
754                         __R_C:          parseInt( '00101', 2), // hasCreateMenu
755                         __RW_:          parseInt( '00110', 2), // isWritable
756                         __RWC:          parseInt( '00111', 2), // isWritable
757                         _S___:          parseInt( '01000', 2), // childrenIsSortable
758                         _S__C:          parseInt( '01001', 2),
759                         _S_W_:          parseInt( '01010', 2),
760                         _S_WC:          parseInt( '01011', 2),
761                         _SR__:          parseInt( '01100', 2),
762                         _SR_C:          parseInt( '01101', 2),
763                         _SRW_:          parseInt( '01110', 2),
764                         _SRWC:          parseInt( '01111', 2),
765                         D____:          parseInt( '10000', 2),
766                         D___C:          parseInt( '10001', 2), // hasCreateMenu
767                         D__W_:          parseInt( '10010', 2), // isWritable
768                         D__WC:          parseInt( '10011', 2), // isWritable
769                         D_R__:          parseInt( '10100', 2), // isRenamable
770                         D_R_C:          parseInt( '10101', 2), // hasCreateMenu
771                         D_RW_:          parseInt( '10110', 2), // isWritable
772                         D_RWC:          parseInt( '10111', 2), // isWritable
773                         DS___:          parseInt( '11000', 2), // childrenIsSortable
774                         DS__C:          parseInt( '11001', 2),
775                         DS_W_:          parseInt( '11010', 2),
776                         DS_WC:          parseInt( '11011', 2),
777                         DSR__:          parseInt( '11100', 2),
778                         DSR_C:          parseInt( '11101', 2),
779                         DSRW_:          parseInt( '11110', 2),
780                         DSRWC:          parseInt( '11111', 2),
781                         CREATE:         1,
782                         WRAITE:         2,
783                         RENAME:         4,
784                         SORT:           8,
785                         DELETE:         16
786                 },
787                 TREE_EVENT: {
788                         UPDATE:                         'onTreeUpdate'
789                 },
790                 FILE_EVENT: {
791                         UPDATE_ATTRIVUTE:       'onFileUpdate',
792                         GET_SEQENTIAL_FILES:'gotSeqentilFiles'
793                 },
794                 FILE_DATA_PROPERTY_RESERVED: [
795                         'children', 'driver', 'state', 'type'
796                 ]
797         }
798 })();
799
800 pettanr.finder = ( function(){
801         var FINDER_ARRAY = [],
802                 ELM_ORIGIN_FINDER_LOCATION_ITEM = pettanr.util.pullHtmlAsTemplete( 'templete-finder-location-item'),
803                 ELM_ORIGIN_FINDER_ICON = ( function(){
804                                 var forIE = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon-ie'),
805                                         modern = pettanr.util.pullHtmlAsTemplete( 'templete-finder-icon');
806                                 return pettanr.ua.isIE === true && pettanr.ua.ieVersion < 8 ? forIE : modern;
807                         })(),
808                 ELM_ORIGIN_CONTAINER = pettanr.util.pullHtmlAsTemplete( 'templete-finder-container'),
809                 ICON_HEIGHT = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON).height,
810                 ICON_CLASSNAME = 'finder-icon-thumbnail',
811                 FINDER_ICON_POOL = [],
812                 BREAD_OBJECT_POOL = [];
813         
814         var FinderIconClass = function(){
815                 var elmContainer,
816                         ELM_WRAPPER = ELM_ORIGIN_FINDER_ICON.cloneNode( true),
817                         ELM_THUMBNAIL = pettanr.util.getElementsByClassName( ELM_WRAPPER, ICON_CLASSNAME )[0],
818                         ELM_FILENAME = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-filename' )[0],
819                         ELM_DESCRIPTION = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-summary' )[0],
820                         ELM_EDITOR_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-editor-apps' )[0],
821                         ELM_VIEWER_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-viewer-apps' )[0],
822                         ELM_ACTION_BUTTON = pettanr.util.getElementsByClassName( ELM_WRAPPER, 'finder-icon-console-action' )[0],
823                         file, w, index, style, instansce,
824                         onDownCallback, onEditorCallback, onViewerCallback, onActionCallback,
825                         viewerList, editorList;
826                 
827                 ELM_WRAPPER.onclick = onDownClick;
828                 function onDownClick(){
829                         onDownCallback( index);
830                         return false;
831                 }
832                 ELM_EDITOR_BUTTON.onclick = onEditorClick;
833                 function onEditorClick(){
834                         onEditorCallback( file, editorList[ 0 ] );
835                         return false;
836                 }
837                 ELM_VIEWER_BUTTON.onclick = onViwerClick;
838                 function onViwerClick(){
839                         onViewerCallback( file, viewerList[ 0 ] );
840                         return false;
841                 }
842                 ELM_ACTION_BUTTON.onclick = onActionClick;
843                 function onActionClick(){
844                         onActionCallback( file );
845                         return false;
846                 }
847                 function draw(){
848                         var _thumb = file.getThumbnail();
849                         if( _thumb.image ){
850                                 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' has-thumbnail';
851                                 ELM_THUMBNAIL.style.backgroundImage = [ 'url(', _thumb.image, ')'].join( '');
852                         } else {
853                                 ELM_THUMBNAIL.className = ICON_CLASSNAME + ' ' + _thumb.className;
854                                 ELM_THUMBNAIL.style.backgroundImage = '';
855                         }
856                         ELM_FILENAME.firstChild.data = file.getName();
857                         ELM_DESCRIPTION.firstChild.data = file.getSummary();
858                         
859                         if( Type.isArray( viewerList ) === true && viewerList.length > 0 ){
860                                 ELM_VIEWER_BUTTON.style.display = '';
861                         } else {
862                                 ELM_VIEWER_BUTTON.style.display = 'none';
863                         };
864                         if( Type.isArray( editorList ) === true && editorList.length > 0 ){
865                                 ELM_EDITOR_BUTTON.style.display = '';
866                         } else {
867                                 ELM_EDITOR_BUTTON.style.display = 'none';
868                         };
869                 }
870                 function resize(){
871                         // ELM_WRAPPER.style.top = (index * ICON_HEIGHT) +'px';
872                 }
873                 function onCollect(){
874                         elmContainer.removeChild( ELM_WRAPPER );
875                         elmContainer = null;
876                         FINDER_ICON_POOL.push( instansce );
877                 }
878                 
879                 return {
880                         init: function( _file, _elmContainer, _w, _index, _style, _onDownCallback, _onEditorCallback, _onViewerCallback, _onActionCallback ){
881                                 instansce = this;
882                                 if( elmContainer !== _elmContainer){
883                                         _elmContainer.appendChild( ELM_WRAPPER);
884                                         elmContainer = _elmContainer;
885                                 }
886                                 if( file !== _file){
887                                         file && file.destroy();
888                                         file = _file;
889                                         viewerList = file.viewerApplicationList();
890                                         editorList = file.editorApplicationList();
891                                         draw();
892                                 }
893                                 if( index !== _index){
894                                         index = _index;
895                                         resize();
896                                 }
897                                 onDownCallback = _onDownCallback;
898                                 onEditorCallback = _onEditorCallback;
899                                 onViewerCallback = _onViewerCallback;
900                                 onActionCallback = _onActionCallback;
901                         },
902                         elm: ELM_WRAPPER,
903                         index: function( _index){
904                                 
905                                 return index;
906                         },
907                         style: function( _style){
908                                 
909                                 return style;
910                         },
911                         onResize: function( w ){
912                                 
913                         },
914                         destroy: function(){
915                                 elmContainer.removeChild( ELM_WRAPPER );
916                                 file && file.destroy();
917                                 file = elmContainer = onDownCallback = onEditorCallback = onViewerCallback = onActionCallback = viewerList = editorList = null;
918                                 FINDER_ICON_POOL.push( instansce);
919                         }
920                 }
921         }
922         function updateIconPosition( _style, _w, _index, _elm){
923                 
924         }
925         var BreadcrumbClass = function(){
926                 var elmContainer,
927                         ELM_WRAPPER = ELM_ORIGIN_FINDER_LOCATION_ITEM.cloneNode( true),
928                         ELM_FILENAME = ELM_WRAPPER.getElementsByTagName( 'a')[0],
929                         file, w, index, instansce,
930                         callback;
931                 ELM_WRAPPER.onclick = onClick;
932                 function draw(){
933                         ELM_FILENAME.className = 'file-icon-' +file.getType();
934                         ELM_FILENAME.innerHTML = file.getName();
935                 }
936                 function resize( index){
937                         ELM_WRAPPER.style.left = (index * 90) +'px';
938                 }
939                 function onClick(){
940                         callback( index);
941                         return false;
942                 }
943
944                 return {
945                         init: function( _file, _elmContainer, _index, _callback ){
946                                 instansce = this;
947                                 if( elmContainer !== _elmContainer ){
948                                         _elmContainer.appendChild( ELM_WRAPPER);
949                                         elmContainer = _elmContainer;
950                                 }
951                                 if( file !== _file){
952                                         file = _file;
953                                         draw();
954                                 }
955                                 if( index !== _index){
956                                         index = _index;
957                                         resize( index);
958                                 }
959                                 callback = _callback;
960                         },
961                         elm: ELM_WRAPPER,
962                         index: function( _index){
963                                 
964                                 return index;
965                         },
966                         onResize: function( w){
967                                 
968                         },
969                         destroy: function(){
970                                 elmContainer.removeChild( ELM_WRAPPER);
971                                 file = elmContainer = null;
972                                 BREAD_OBJECT_POOL.push( this );
973                         }
974                 }
975         }
976         
977         var FinderClass = function( ELM_CONTAINER, tree, header, footer ){
978                 var ICON_ARRAY = [],
979                         BREAD_ARRAY = [],
980                         elmContainer = ELM_ORIGIN_CONTAINER.cloneNode( true ),
981                         elmLocation = elmContainer.getElementsByTagName( 'ul' )[0],
982                         nodesDiv = elmContainer.getElementsByTagName( 'div' ),
983                         elmSidebarButton = nodesDiv[1],
984                         elmStyleButton = nodesDiv[2],
985                         elmActionButton = nodesDiv[3],
986                         elmBody = nodesDiv[ nodesDiv.length -1 ],
987                         //tree = pettanr.file.createTree( TREE_TYPE),
988                         headX,
989                         headY,
990                         headH = pettanr.util.getElementSize( nodesDiv[0] ).height,
991                         bodyY,
992                         currentFile = null,
993                         breadW = 90,
994                         size = pettanr.util.getElementSize( ELM_ORIGIN_FINDER_ICON ),
995                         iconW = size.width,
996                         iconH = size.height,
997                         style = 0,
998                         w, h, bodyH,
999                         instance = this;
1000                         
1001                 tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, draw );
1002                 ELM_CONTAINER.appendChild( elmContainer );
1003                 
1004                 function draw( _w, _h ){
1005                         w = Type.isFinite( _w ) === true ? _w : w;
1006                         h = Type.isFinite( _h ) === true ? _h : h;
1007                         bodyH = h - headH;
1008                         var     l = tree.hierarchy() +1,
1009                                 m = BREAD_ARRAY.length,
1010                                 _file, _bread;
1011                         for(var i=0; i<l; ++i){
1012                                 _file = i !== l-1 ? tree.getParentFileAt( i) : tree.getCurrentFile();
1013                                 if( i < m){
1014                                         BREAD_ARRAY[ i].init( _file, elmLocation, i, onHeadClick);
1015                                 } else {
1016                                         BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick ));
1017                                 }
1018                         }
1019                         while( l < BREAD_ARRAY.length){
1020                                 BREAD_ARRAY.pop().destroy();
1021                         }
1022                         
1023                         l = _file.getChildFileLength();
1024                         m = ICON_ARRAY.length;
1025
1026                         for( i=0; i<l; ++i){
1027                                 if( i < m){
1028                                         ICON_ARRAY[ i ].init( _file.getChildFileByIndex( i), elmBody, w, i, style, onDown, onEditor, onViwer, onAction );
1029                                 } else {
1030                                         ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i), elmBody, _w, i, style, onDown, onEditor, onViwer, onAction ));
1031                                 }
1032                         }
1033                         if( _file.getState() === pettanr.file.FILE_STATE.LOADING ){
1034                                 elmBody.className = 'finder-body loading';
1035                         } else {
1036                                 elmBody.className = 'finder-body';
1037                         }
1038                         
1039                         elmBody.style.height = bodyH + 'px';
1040                         
1041                         while( l < ICON_ARRAY.length){
1042                                 ICON_ARRAY.pop().destroy();
1043                         }
1044                 }
1045                 
1046                 function onHeadClick( i){
1047                         var l = BREAD_ARRAY.length -1;
1048                         if( i < l){
1049                                 var _file = tree.getParentFileAt( i);
1050                                 if( _file !== null){
1051                                         tree.up( i);
1052                                         draw( w, h );
1053                                 }
1054                         }
1055                 }
1056                 function onDown( i ){
1057                         if( i < ICON_ARRAY.length ){
1058                                 var _file = tree.getCurrentFile().getChildFileByIndex( i );
1059                                 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === pettanr.file.FILE_TYPE.FOLDER)){
1060                                         tree.down( i );
1061                                         draw( w, h );
1062                                 }
1063                         }
1064                 }
1065                 function onEditor( _file, _app ){
1066                         _app.boot( _file );
1067                 }
1068                 function onViwer( _file, _app ){
1069                         _app.bootInOverlay( _file );
1070                 }
1071                 function onAction( _file ){
1072
1073                 }
1074                 this.rootElement = elmContainer;
1075                 this.parentElement = ELM_CONTAINER;
1076                 this.displayName = 'finder';
1077                 this.ID = 'finder';
1078                 this.MIN_WIDTH = 240;
1079                 this.MIN_HEIGHT = 240;
1080                 this.init = function(){
1081                         //$( elmLocation).click( onHeadClick);
1082                         //$( elmContainer).click( onBodyClick);
1083                         var position = pettanr.util.getAbsolutePosition( elmLocation );
1084                         headX = position.x;
1085                         headY = position.y;
1086                         bodyY = pettanr.util.getAbsolutePosition( elmBody ).y;
1087                         delete instance.init;
1088                 }
1089                 this.onPaneResize = function( _w, _h ){
1090                         instance.init && instance.init();
1091                         draw( _w, _h );                 
1092                         
1093                         w = _w;
1094                         h = _h;
1095                         elmBody.style.height = ( _h - headH ) + 'px';
1096                         
1097                         for(var i=0, l=ICON_ARRAY.length; i<l; ++i){
1098                                 ICON_ARRAY[ i].onResize( _w );
1099                         }
1100                 }
1101         }
1102         FinderClass.prototype = pettanr.view._getAbstractApplication();
1103         
1104         function getFinderIcon( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction){
1105                 var _icon;
1106                 if( FINDER_ICON_POOL.length > 0){
1107                         _icon = FINDER_ICON_POOL.shift();
1108                 } else {
1109                         _icon = new FinderIconClass();
1110                 }
1111                 _icon.init( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction );
1112                 return _icon;
1113         }
1114         
1115         function getBreadcrumb( _file, _elmContainer, index, callback){
1116                 var _bread;
1117                 if( BREAD_OBJECT_POOL.length > 0){
1118                         _bread = BREAD_OBJECT_POOL.shift();
1119                 } else {
1120                         _bread = new BreadcrumbClass();
1121                 }
1122                 _bread.init( _file, _elmContainer, index, callback);
1123                 return _bread;
1124         }
1125
1126         return {
1127                 init: function(){
1128                         
1129                 },
1130                 createFinder: function( _applicationReference, _elmTarget, _tree, _header, _footer ){
1131                         if( pettanr.view.isApplicationReference( _applicationReference ) === false ) return;
1132                         
1133                         var _finder = new FinderClass( _elmTarget, _tree, _header, _footer );
1134                         FINDER_ARRAY.push( _finder );
1135                         return _finder;
1136                 },
1137                 registerFinderHead: function(){
1138                         
1139                 },
1140                 registerFinderPane: function( _finderPane){
1141                         
1142                 },
1143                 isFinderInstance: function( _finder){
1144                         return _finder instanceof FinderClass;
1145                 },
1146                 isFinderPaneInstance: function(){
1147                         
1148                 },
1149                 isFinderHeadInstance: function(){
1150                 }
1151         }
1152 })();
1153
1154
1155 pettanr.driver = ( function(){
1156         var MyAuthorID = 'current_author' in window ? current_author.id : ( pettanr.DEBUG ? 1 : -1 ),
1157                 MyArtistID = 'current_artist' in window ? current_artist.id : ( pettanr.DEBUG ? 1 : -1 ),
1158                 Driver = {
1159                         getSeqentialFiles: function( _file){
1160                                 var _data = FileAPI.getFileData( _file),
1161                                         _json = _data !== null ? _data.json : null;
1162                                 if( _json === true && _data.type === pettanr.driver.FILE_TYPE.COMIC ){
1163                                         if( pettanr.LOCAL === true ){
1164                                                 _json = [ 'json\/comics_', _data.id, '.json' ].join( '' );
1165                                         } else {
1166                                                 _json = [ pettanr.CONST.PETTANR_ROOT_PATH, 'comics\/', _data.id, '.json\/play\/' ].join( '' );
1167                                         }
1168                                 }
1169                                 if( typeof _json === 'string'){
1170                                         FileAPI.getJson( _file, _json, onLoadJson, onErrorJson);
1171                                         _data.state = pettanr.file.FILE_STATE.LOADING;
1172                                         _data.json = null;
1173                                         return;
1174                                 }
1175                         },
1176                         getName: function( _file){
1177                                 var _data = FileAPI.getFileData( _file),
1178                                         _type = _data !== null ? _data.type : null;
1179                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
1180                                         return [ _data.id, _data.ext ].join( '.');
1181                                 } else
1182                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1183                                         return [ _data.t, ':', _data.comic.title ].join( '');
1184                                 } else
1185                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1186                                         return _data.title;
1187                                 } else
1188                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
1189                                         return [ _data.name, '画伯' ].join( '');
1190                                 } else
1191                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR ){
1192                                         return [ _data.name, '先生' ].join( '');
1193                                 }
1194                                 return _data.name;
1195                         },
1196                         getThumbnail: function( _file){
1197                                 var _data = FileAPI.getFileData( _file),
1198                                         _type = _data !== null ? _data.type : null;
1199                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1200                                         return { image: [ pettanr.CONST.RESOURCE_PICTURE_PATH, 'thumbnail/', _data.id, '.', _data.ext ].join( '')};
1201                                 }
1202                                 if( _data === FILE_DATA_COMICS_ROOT){
1203                                         return { className: 'file-type-cabinet'};
1204                                 }
1205                                 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1206                                         return { className: 'file-type-comic'};
1207                                 }
1208                                 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1209                                         return { className: 'file-type-panel'};
1210                                 }
1211                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1212                                         return { className: 'file-type-author'};
1213                                 }
1214                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1215                                         return { className: 'file-type-artist'};
1216                                 }
1217                                 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1218                                         return { className: 'file-type-folder'};
1219                                 }
1220                                 return { className: 'file-type-broken'};
1221                         },
1222                         getSummary: function( _file ){
1223                                 var _data = FileAPI.getFileData( _file),
1224                                         _type = _data !== null ? _data.type : null;
1225                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1226                                         return [ _data.width, 'x', _data.height, ', filesize:', _data.filesize, ', lisence:', _data.license ].join( '' );
1227                                 }
1228                                 if( _data === FILE_DATA_COMICS_ROOT){
1229                                         return 'cabinet file';
1230                                 }
1231                                 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1232                                         return 'comic file, id:' + _data.id;
1233                                 }
1234                                 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1235                                         return [ _data.width, 'x', _data.height ].join( '' );
1236                                 }
1237                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1238                                         return 'author file, id:' + _data.id;
1239                                 }
1240                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1241                                         return [ 'id:', _data.id, ' Email:', _data.email || 'empty' , ', HP:', _data.homepage_url || 'empty' ].join( '' );
1242                                 }
1243                                 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1244                                         return 'pettanR folder';
1245                                 }
1246                                 return 'pettanR unknown file';
1247                         },
1248                         write: function( _file, _newData, _onUpdateFunction ){
1249                                 var _data = FileAPI.getFileData( _file ),
1250                                         _type = _data !== null ? _data.type : null;
1251                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1252                                 }
1253                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1254                                 }
1255                                 if( _type === pettanr.driver.FILE_TYPE.PANEL_PICTURE ){
1256                                         
1257                                 }
1258                                 if( _type === pettanr.driver.FILE_TYPE.BALLOON ){
1259                                 }
1260                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
1261                                 }                               
1262                         },
1263                         viewerApplicationList: function( _file ){
1264                                 var _data = FileAPI.getFileData( _file ),
1265                                         _type = _data !== null ? _data.type : null;
1266                                         
1267                                 if( _data === FILE_DATA_MY_PICTURES_ROOT ){
1268                                         return [ pettanr.premiumSatge ];
1269                                 }
1270                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
1271                                         return [ pettanr.premiumSatge ];
1272                                 }
1273                                 return [];
1274                         },
1275                         editorApplicationList: function( _file ){
1276                                 var _data = FileAPI.getFileData( _file ),
1277                                         _type = _data !== null ? _data.type : null;
1278                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1279                                         return [ pettanr.editor ];
1280                                 }
1281                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1282                                         return [ pettanr.editor, pettanr.comicConsole ];
1283                                 }
1284                                 return [];
1285                         }
1286                 },
1287                 FileAPI = pettanr.file.registerDriver( Driver ),
1288                 FILE_DATA_SERVICE_ROOT = {
1289                         name:           'PettanR root',
1290                         type:           pettanr.file.FILE_TYPE.FOLDER,
1291                         children:       []
1292                 },
1293                 FILE_DATA_COMICS_ROOT = {
1294                         name:           'Comics',
1295                         type:           pettanr.file.FILE_TYPE.FOLDER,
1296                         children:       [],
1297                         driver:         Driver,
1298                         json:           pettanr.CONST.URL_COMICS_JSON
1299                 },
1300                 FILE_DATA_PANELS_ROOT = {
1301                         name:           'Panels',
1302                         type:           pettanr.file.FILE_TYPE.FOLDER,
1303                         children:       [],
1304                         driver:         Driver,
1305                         json:           pettanr.CONST.URL_PANELS_JSON
1306                 },
1307                 FILE_DATA_PICTURE_ROOT = {
1308                         name:           'Picutures',
1309                         type:           pettanr.file.FILE_TYPE.FOLDER,
1310                         children:       [],
1311                         driver:         Driver,
1312                         json:           pettanr.CONST.URL_RESOURCE_PICTURES_JSON
1313                 },
1314                 FILE_DATA_MY_COMICS_ROOT = {
1315                         name:           'My Comics',
1316                         type:           pettanr.file.FILE_TYPE.FOLDER,
1317                         children:       [],
1318                         driver:         Driver,
1319                         id:                     MyAuthorID
1320                 },
1321                 FILE_DATA_LATEST_COMICS = {
1322                         name:           'Latest Comics',
1323                         type:           pettanr.file.FILE_TYPE.FOLDER,
1324                         children:       []
1325                 },
1326                 FILE_DATA_MY_PICTURES_ROOT = {
1327                         name:           'My Pictures',
1328                         type:           pettanr.file.FILE_TYPE.FOLDER,
1329                         children:       [],
1330                         driver:         Driver,
1331                         json:           pettanr.CONST.URL_ORIGINAL_PICTURES_JSON,
1332                         id:                     MyArtistID
1333                 },
1334                 FILE_DATA_AUTHOR_ROOT = {
1335                         name:           'Authors',
1336                         type:           pettanr.file.FILE_TYPE.FOLDER,
1337                         children:       []
1338                 },
1339                 FILE_DATA_ARTIST_ROOT = {
1340                         name:           'Artists',
1341                         type:           pettanr.file.FILE_TYPE.FOLDER,
1342                         children:       []
1343                 },
1344                 FILE_DATA_LISENCE_ROOT = {
1345                         name:           'Original Lisences',
1346                         type:           pettanr.file.FILE_TYPE.FOLDER,
1347                         children:       []
1348                 },
1349                 FILE_DATA_BALLOON_ROOT = {
1350                         name:           'Balloon templetes',
1351                         type:           pettanr.file.FILE_TYPE.FOLDER,
1352                         children:       []
1353                 },
1354                 AUTHOR_ARRAY = [],
1355                 ARTIST_ARRAY = [],
1356                 PANEL_ARRAY = [],
1357                 COMIC_ARRAY = [],
1358                 RESOURCE_PICTURE_ARRAY = [],
1359                 BALLOON_TEMPLETE_ARRAY = [],
1360                 ORIGINAL_LICENSE_ARRAY = [],
1361                 BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ',');
1362         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);
1363         FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_LATEST_COMICS, FILE_DATA_AUTHOR_ROOT);
1364         FILE_DATA_PICTURE_ROOT.children.push( FILE_DATA_MY_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT);
1365         
1366         FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT);
1367
1368         function onLoadJson( _file, _json ){
1369                 var _access = FileAPI.getFileDataAccess( _file),
1370                         _data = _access !== null ? _access.DATA : null,
1371                         l;
1372                 if( _data === null){
1373                         onErrorJson( _file);
1374                         return;
1375                 }
1376                 _data.state = pettanr.file.FILE_STATE.OK;
1377                 
1378                 if( Type.isArray( _json ) === true ){
1379                         l = _json.length;
1380                         if( l === 0) return;
1381                         for( var i=0; i<l; ++i ){
1382                                 buildFileData( _json[ i], _data);
1383                         }                       
1384                 } else
1385                 if( _json.id ){
1386                         buildFileData( _json, _data );
1387                 }
1388                 _access.dispatchFileEvent( FileAPI.createFileEvent( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, _file, 'children', null));
1389         }
1390         function onErrorJson( _file ){ 
1391                 var _data = FileAPI.getFileData( _file);
1392                 if( _data !== null){
1393                         _data.state = pettanr.file.FILE_STATE.ERROR;
1394                 }
1395         }
1396         function buildFileData( _data, _parent ){
1397                 var _array, i, l;
1398                 // Panel
1399                 if( _parent === FILE_DATA_PANELS_ROOT ){
1400                         _data.type = pettanr.driver.FILE_TYPE.PANEL;
1401                         _array = PANEL_ARRAY;
1402                 } else
1403                 // Comic
1404                 if( _parent === FILE_DATA_COMICS_ROOT ){
1405                         _data.type = pettanr.driver.FILE_TYPE.COMIC;
1406                         _array = COMIC_ARRAY;
1407                 } else
1408                 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC ){
1409                         _array = COMIC_ARRAY;
1410                 } else
1411                 // Lisence
1412                 if( _parent === FILE_DATA_LISENCE_ROOT ){
1413                         _data.type = pettanr.driver.FILE_TYPE.LICENSE;
1414                         _array = ORIGINAL_LICENSE_ARRAY;
1415                 } else
1416                 // Author
1417                 if( _parent === FILE_DATA_AUTHOR_ROOT ){
1418                         _data.type = pettanr.driver.FILE_TYPE.AUTHOR;
1419                         _array = AUTHOR_ARRAY;
1420                 } else
1421                 // Artist
1422                 if( _parent === FILE_DATA_ARTIST_ROOT ){
1423                         _data.type = pettanr.driver.FILE_TYPE.ARTIST;
1424                         _array = ARTIST_ARRAY;
1425                 } else          
1426                 // Picture
1427                 if( _parent === FILE_DATA_PICTURE_ROOT || _parent === FILE_DATA_MY_PICTURES_ROOT ){
1428                         _data.type = pettanr.driver.FILE_TYPE.PICTURE;
1429                         _array = RESOURCE_PICTURE_ARRAY;
1430                         // original_license を含まなければ、license object を削除して ビットデータ で保持
1431                         // original_license なら ファイルを作る buildFileData( _license, FILE_DATA_LISENCE_ROOT)
1432                         var _license = _data.license,
1433                                 _rule,
1434                                 _Math_pow = Math.pow,
1435                                 _bits = 0;
1436                         if( typeof _license === 'object'){
1437                                 for( i=0, l=BASIC_LICENSES.length; i<l; ++i){
1438                                         _rule = _license[ BASIC_LICENSES[ i]]
1439                                         if( typeof _rule === 'number' && _rule === 1 ){
1440                                                 _bits += _Math_pow( 2, i);
1441                                         }
1442                                 }
1443                                 _data.license = _bits;
1444                         }
1445                 } else {
1446                         alert( 'error' );
1447                 }
1448                 
1449                 _data.driver = Driver;
1450                 
1451                 // _array に _data を格納 または 上書き
1452                 if( typeof _data.id === 'number' && _data.id > 0 ){
1453                         var _id = _data.id - 1,
1454                                 __data = _array[ _id ],
1455                                 _reserved = pettanr.file.FILE_DATA_PROPERTY_RESERVED.join( ', ' );
1456                         if( __data ){
1457                                 for( var key in _data){
1458                                         if( _reserved.indexOf( key ) === -1 ){
1459                                                 __data[ key ] = _data[ key ];
1460                                         }
1461                                 }
1462                                 _data = __data; // このタイミングで参照が切れるので注意!!
1463                         } else {
1464                                 _array[ _id ] = _data;
1465                         }
1466                 } else {
1467                         alert( 'error' );
1468                 }
1469
1470                 // Author
1471                 // Artist
1472                 if( _parent === FILE_DATA_AUTHOR_ROOT || _parent === FILE_DATA_ARTIST_ROOT ){
1473                         addChildData( _parent, _data );
1474                 } else
1475                 // Comic + Panels
1476                 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC || _parent === FILE_DATA_COMICS_ROOT ){
1477                         var _panels = _data.panels,
1478                                 _panel;
1479                         if( _panels && Type.isArray( _panels ) === true ){
1480                                 
1481                                 for( i=0, l=_panels.length; i<l; ++i){
1482                                         _panel = buildFileData( _panels[ i ], FILE_DATA_PANELS_ROOT );
1483                                         /*
1484                                          * 間違い! t 順に格納
1485                                          */
1486                                         addChildData( _data, _panel );
1487                                 }
1488                                 delete _data.panels;
1489                         } else {
1490                                 if( _data.json !== null ){
1491                                         _data.json = true;
1492                                 }
1493                                 if( Type.isArray( _data.children ) === false ){
1494                                         _data.children = [];
1495                                 }                               
1496                         }
1497                         var _author = _data.author || getResource( AUTHOR_ARRAY, _data.author_id );
1498                         if( _author ){
1499                                 _data.author = _author = buildFileData( _author, FILE_DATA_AUTHOR_ROOT );
1500                                 addChildData( _author, _data );
1501                                 _author.id === MyAuthorID && addChildData( FILE_DATA_MY_COMICS_ROOT, _data );
1502                         }
1503                         if( _parent === FILE_DATA_COMICS_ROOT ){
1504                                 addChildData( FILE_DATA_LATEST_COMICS, _data);
1505                         }
1506                 } else
1507                 // Panel
1508                 if( _parent === FILE_DATA_PANELS_ROOT ){
1509                         _data.comic = getResource( COMIC_ARRAY, _data.comic_id );
1510                         _data.author = getResource( AUTHOR_ARRAY, _data.author_id );
1511
1512                         // picture data をファイルに取り出し
1513                         var _elements = _data.panel_elements,
1514                                 _elm;
1515                         if( Type.isArray( _elements ) === true ){
1516                                 for( i=0, l=_elements.length; i<l; ++i){
1517                                         _elm = _elements[ i];
1518                                         if( _elm.resource_picture ){
1519                                                 _elm.resource_picture = buildFileData( _elm.resource_picture, FILE_DATA_PICTURE_ROOT ); // 上記参照切れに備えてここで上書き
1520                                         } else {
1521                                                 _elm.resource_picture = getResource( RESOURCE_PICTURE_ARRAY, _elm.resource_picture_id );
1522                                         }
1523                                 }                               
1524                         }
1525                 } else
1526                 // Picture
1527                 if( _data.type == pettanr.driver.FILE_TYPE.PICTURE ){
1528                         var _artist = _data.artist || getResource( ARTIST_ARRAY, _data.artist_id );
1529                         if( _artist){
1530                                 _data.artist = _artist = buildFileData( _artist, FILE_DATA_ARTIST_ROOT );
1531                                 addChildData( _artist, _data );
1532                                 if( _artist.id === MyArtistID ){
1533                                         addChildData( FILE_DATA_MY_PICTURES_ROOT, _data );
1534                                         //FILE_DATA_MY_PICTURES_ROOT.type = pettanr.driver.FILE_TYPE.ARTIST;
1535                                         //FILE_DATA_MY_PICTURES_ROOT.id = MyArtistID;
1536                                 }
1537                         }
1538                 }
1539                 return _data;
1540         }
1541         function addChildData( _parent, _child ){
1542                 if( Type.isArray( _parent.children ) === false){
1543                         _parent.children = [];
1544                 }
1545                 pettanr.util.getIndex( _parent.children, _child ) === -1 && _parent.children.push( _child );
1546         }
1547         function getResource( _array, _id ){
1548                 if( Type.isArray( _array ) === false || Type.isNumber( _id ) === false || _id < 1 ) return null;
1549                 var _data = _array[ _id - 1 ];
1550                 if( !_data ){
1551                         _data = _array[ _id - 1 ] = {};
1552                 }
1553                 return _data;
1554         }
1555
1556         return {
1557                 createComicTree: function(){
1558                         return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT ); //FILE_DATA_COMICS_ROOT);
1559                 },
1560                 createPictureTree: function(){
1561                         return pettanr.file.createTree( FILE_DATA_PICTURE_ROOT );
1562                 },
1563                 createArtistTree: function(){
1564                         return pettanr.file.createTree( FILE_DATA_ARTIST_ROOT );
1565                 },
1566                 createServiceTree: function(){
1567                         return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT );
1568                 },
1569                 isPettanrFileInstance: function( _file ){
1570                         if( pettanr.file.isFileInstance( _file ) === true){
1571                                 var _data = FileAPI.getFileData( _file);
1572                                 return _data !== null && _data.driver === Driver;
1573                         }
1574                         return false;
1575                 },
1576                 _getAPI: function(){
1577                         return FileAPI;
1578                 },
1579                 _getPictureRootData: function(){
1580                         return FILE_DATA_PICTURE_ROOT;
1581                 },
1582                 _getMyPicturesData: function(){
1583                         return FILE_DATA_MY_PICTURES_ROOT;
1584                 },
1585                 FILE_TYPE: {
1586                         COMIC:                          FileAPI.createFileTypeID(),
1587                         PANEL:                          FileAPI.createFileTypeID(),
1588                         PICTURE:                        FileAPI.createFileTypeID(),
1589                         PANEL_PICTURE:          FileAPI.createFileTypeID(),
1590                         BALLOON:                        FileAPI.createFileTypeID(),
1591                         AUTHOR:                         FileAPI.createFileTypeID(),
1592                         ARTIST:                         FileAPI.createFileTypeID(),
1593                         LICENSE:                        FileAPI.createFileTypeID()
1594                 }
1595         }
1596 })();
1597
1598 pettanr.entrance = pettanr.view.registerApplication( function(){
1599         var wrap = document.getElementById('inner-wrapper'),
1600                 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height,
1601                 instance = this;
1602         this.displayName = 'Home';
1603         this.ID          = 'Home';
1604         this.rootElement = document.getElementById('entrance');
1605         this.onOpen = function( _w, _h, _option ){
1606                 wrap.style.display = '';
1607                 wrap.style.height = ( _h - pageHeaderH ) + 'px';
1608         }
1609         this.onClose = function(){
1610                 wrap.style.display = 'none';
1611         }
1612         this.onPaneResize = function( _w, _h){
1613                 instance.onOpen( _w, _h );
1614         }
1615 });
1616 pettanr.entrance.addToLancher();
1617
1618 pettanr.cabinet = pettanr.view.registerApplication( function(){
1619         var finder,
1620                 elmContainer = document.getElementById( 'cabinet'),
1621                 option,
1622                 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height;
1623                 
1624         this.displayName = 'Comic list';
1625         this.ID          = 'Comiclist';
1626         this.rootElement = elmContainer;
1627         this.onOpen = function( _w, _h ){
1628                 finder = finder || pettanr.finder.createFinder( pettanr.cabinet, elmContainer, pettanr.driver.createComicTree() );
1629                 finder.resize( _w, _h - pageHeaderH );
1630         }
1631         this.onClose = function(){
1632                 // finder.close();
1633         }
1634         this.onPaneResize = function( _w, _h){
1635                 finder.resize( _w, _h - pageHeaderH );
1636         }
1637 });
1638 pettanr.cabinet.addToLancher();
1639
1640 pettanr.gallery = pettanr.view.registerApplication( function(){
1641         var finder,
1642                 elmContainer = document.getElementById( 'gallery' ),
1643                 option,
1644                 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height;
1645                 
1646         this.displayName = 'Pictures';
1647         this.ID          = 'pictures';
1648         this.rootElement = elmContainer;
1649         this.onOpen = function( _w, _h ){
1650                 finder = finder || pettanr.finder.createFinder( pettanr.gallery, elmContainer, pettanr.driver.createPictureTree() );
1651                 finder.resize( _w, _h - pageHeaderH );
1652         }
1653         this.onClose = function(){
1654                 // finder.close();
1655         }
1656         this.onPaneResize = function( _w, _h){
1657                 finder.resize( _w, _h - pageHeaderH );
1658         }
1659 });
1660 pettanr.gallery.addToLancher();
1661
1662 pettanr.backyard = pettanr.view.registerApplication( function(){
1663         this.displayName = 'Settings';
1664         this.ID          = 'Settinds';
1665         this.rootElement = document.getElementById( 'backyard' );
1666         this.onOpen = function( _w, _h, _option ){
1667         }
1668         this.onClose = function(){
1669         }
1670         this.onPaneResize = function( _w, _h){
1671         }
1672 });
1673 pettanr.backyard.addToLancher();
1674
1675 if( pettanr.DEBUG === true){
1676         pettanr.debug = pettanr.view.registerApplication( function(){
1677                 var elmDl = document.getElementById( 'useragent'),
1678                         elmDt, elmDd,
1679                         data = {
1680                                 pettanR:        pettanr.version,
1681                                 ua:                     navigator.userAgent,
1682                                 platform:       navigator.platform,
1683                                 appVersion:     navigator.appVersion,
1684                                 appCodeName:navigator.appCodeName,
1685                                 appName:        navigator.appName,
1686                                 language:       navigator.browserLanguage || navigator.language,
1687                                 ActiveX:        pettanr.ua.ACTIVEX
1688                         },
1689                         ua = pettanr.ua;
1690                 if( ua.IE){
1691                         //data.ua = 'Internet Explorer';
1692                         data.version = ua.IE;
1693                         if( ua.ieVersion >= 8) data.RenderingVersion = ua.ieRenderingVersion;
1694                         data.browserType = ua.STANDALONE === true ? 'Standalone' : 'bundle';
1695                         if( ua.ieVersion < 9) {
1696                                 data.vml = ua.VML;
1697                         } else {
1698                                 data.svg = ua.SVG;
1699                         }
1700                 }
1701                 data.RenderingMode = ua.isStanderdMode === true ? 'Standerd' : 'Quirks';
1702                 
1703                 for( var key in data){
1704                         elmDt = document.createElement( 'dt');
1705                         elmDt.innerHTML = key;
1706                         elmDd = document.createElement( 'dd');
1707                         elmDd.innerHTML = '' + data[ key];
1708                         if( !data[ key]) elmDd.style.color = 'red';
1709                         elmDl.appendChild( elmDt);
1710                         elmDl.appendChild( elmDd);
1711                 }
1712                 
1713                 var wrap = document.getElementById('inner-wrapper'),
1714                         pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' )).height,
1715                         instance = this;
1716                 
1717                 this.displayName = 'Debug';
1718                 this.ID          = 'debug';
1719                 this.rootElement = document.getElementById( 'debug' );
1720                 this.onOpen = function( _w, _h, _option ){
1721                         wrap.style.display = '';
1722                         wrap.style.height = ( _h - pageHeaderH ) + 'px';
1723                 }
1724                 this.onClose = function(){
1725                         wrap.style.display = 'none';
1726                 }
1727                 this.onPaneResize = function( _w, _h ){
1728                         instance.onOpen( _w, _h );
1729                 }
1730         });
1731         pettanr.debug.addToLancher();
1732         
1733 } else {
1734         var _debug = document.getElementById( 'debug');
1735         if( _debug){
1736                 pettanr.util.removeAllChildren( _debug);
1737                 _debug.parentNode.removeChild( _debug);
1738                 _debug = null;
1739         }
1740 }
1741
1742 /* ----------------------------------------
1743  * Image Group Exproler
1744  *  - overlay
1745  */
1746 pettanr.premiumSatge = pettanr.view.registerApplication( function(){
1747         var ICON_ARRAY = [],
1748                 WHEEL_DELTA = 64,
1749                 ARTIST_TREE = pettanr.driver.createArtistTree(),
1750                 ARTIST_ROOT_FILE = ARTIST_TREE.getRootFile(),
1751                 instance = this,
1752                 winW, winH,
1753                 wrapX,
1754                 elmWrap = document.getElementById( 'image-group-wrapper' ),
1755                 elmContainer = document.getElementById( 'image-group-icon-container' ),
1756                 containerW,
1757                 containerH = pettanr.util.getElementSize( elmContainer ).height,                
1758                 elmIconOrigin = ( function(){
1759                         var ret = document.createElement( 'div' ),
1760                                 data = document.createElement( 'div' );
1761                         ret.appendChild( data );
1762                         ret.className = 'image-group-item';
1763                         data.className = 'image-group-item-title';
1764                         return ret;
1765                 })(),
1766                 jqContainer,
1767                 size = pettanr.util.getElementSize( elmIconOrigin ),
1768                 itemW = size.width,
1769                 itemH = size.height,
1770                 elmName = document.getElementById( 'image-group-name' ),
1771                 elmButton = document.getElementById( 'image-group-button' ),
1772                 buttonW = pettanr.util.getElementSize( elmButton ).width,
1773                 //onUpdateFunction,
1774                 onUpdateFunction = null,
1775                 onUpdateData = null,
1776                 artistID = -1,
1777                 onEnterInterval = null;
1778
1779         elmButton.onclick = clickOK;
1780         
1781         var BASE_PATH = pettanr.LOCAL === true ? 'resource_pictures\/' : pettanr.CONST.PETTANR_ROOT_PATH + 'resource_pictures\/',
1782                 THUMB_PATH = BASE_PATH, // + 'thumbnail/',
1783                 LIMIT_FILESIZE = 1024 * 10; // 10KB
1784
1785         var ImageGroupIconClass = function( INDEX, data ){
1786                 var elmIconWrap     = elmIconOrigin.cloneNode( true ),
1787                         elmIconTitle    = pettanr.util.getElementsByClassName( elmIconWrap, 'image-group-item-title' )[ 0 ],
1788                         SRC             = [ BASE_PATH, data.id, '.', data.ext ].join( ''),
1789                         LOW_SRC         = data.filesize && data.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext ].join( '') : null,
1790                         reversibleImage = null,
1791                         timer           = null,
1792                         onEnterFlag     = false,
1793                         instance        = this;
1794                 elmContainer.appendChild( elmIconWrap );
1795                 elmIconWrap.style.left = ( INDEX * itemW ) + 'px';
1796                 elmIconTitle.appendChild( document.createTextNode( data.filesize + 'bytes' ) );
1797                 
1798                 function onImageLoad( url, _imgW, _imgH ){
1799                         data.width = _imgW = _imgW || data.width || 64;
1800                         data.height = _imgH = _imgH || data.height || 64;
1801                         elmIconTitle.firstChild.data = _imgW + 'x' + _imgH;
1802                         var zoom = 128 /( _imgW > _imgH ? _imgW : _imgH ),
1803                                 MATH_FLOOR = Math.floor,
1804                                 h = MATH_FLOOR( _imgH * zoom ),
1805                                 w = MATH_FLOOR( _imgW * zoom );
1806                         reversibleImage.elm.style.cssText = [
1807                                 'width:',  w, 'px;',
1808                                 'height:', h, 'px;',
1809                                 'margin:', MATH_FLOOR( itemH / 2 - h / 2 ), 'px ', MATH_FLOOR( itemW / 2 - w / 2 ), 'px 0'
1810                         ].join('');
1811                         reversibleImage.resize( w, h );
1812                         elmIconWrap.onclick = onClick;
1813                 }
1814                 
1815                 function onClick(){
1816                         onUpdateData = data;
1817                         pettanr.premiumSatge.shutdown();
1818                 }
1819                 
1820                 function asyncDraw(){
1821                         reversibleImage = pettanr.image.createReversibleImage( LOW_SRC || SRC, itemW, itemH, onImageLoad );
1822                         elmIconWrap.appendChild( reversibleImage.elm );
1823                         onEnterFlag = true;
1824                         timer = null;
1825                 }
1826                 
1827                 this.onEnter = function( delay ){
1828                         timer = window.setTimeout( asyncDraw, delay );
1829                         delete instance.onEnter;
1830                 }
1831                 this.destroy = function(){
1832                         delete instance.destroy;
1833                         timer && window.clearTimeout( timer );
1834                         reversibleImage && reversibleImage.destroy();
1835                         pettanr.util.removeAllChildren( elmIconWrap );
1836                         elmContainer.removeChild( elmIconWrap );
1837                         elmIconWrap.onclick = '';
1838                         reversibleImage = elmIconWrap = elmIconTitle = data = timer = null;
1839                 }
1840         }
1841         
1842         function onEnterShowImage(){
1843                 var l = ICON_ARRAY.length,
1844                         _start = -wrapX /itemW -1,
1845                         _end = _start + winW /itemW +1,
1846                         _icon;
1847                 for( var i=0, c = 0; i<l; ++i){
1848                         _icon = ICON_ARRAY[ i ];
1849                         if( _start < i && i < _end && _icon.onEnter ){
1850                                 _icon.onEnter( c * 100 );
1851                                 c++;
1852                         }
1853                 }
1854                 onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1855                 onEnterInterval = null;
1856         }
1857         function clickOK(){
1858                 pettanr.premiumSatge.shutdown();
1859         }
1860         function onMouseWheel( e, delta ){
1861                 if( winW < containerW){
1862                         wrapX += delta * WHEEL_DELTA;
1863                         wrapX = wrapX > 0 ? 0 : wrapX < winW -containerW ? winW -containerW : wrapX;
1864                         jqContainer.css( { left: wrapX});
1865                         
1866                         onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1867                         onEnterInterval = window.setTimeout( onEnterShowImage, 500 );
1868                 }
1869                 //e.stopPropagation();
1870                 return false;                   
1871         }
1872         
1873         function drawIcons(){
1874                 while( ICON_ARRAY.length > 0 ){
1875                         ICON_ARRAY.shift().destroy();
1876                 }
1877                 
1878                 var _index = ARTIST_ROOT_FILE.search( {
1879                                 id:   artistID,
1880                                 type: pettanr.driver.FILE_TYPE.ARTIST
1881                         })[ 0 ],
1882                         _artistFile = ARTIST_ROOT_FILE.getChildFileByIndex( _index ),
1883                         _file;
1884                 if( _artistFile !== null ){
1885                         for(var i=0, l=_artistFile.getChildFileLength(); i<l; ++i ){
1886                                 _file = _artistFile.getChildFileByIndex( i );
1887                                 ICON_ARRAY.push( new ImageGroupIconClass( i, pettanr.driver._getAPI().getFileData( _file ) ));
1888                                 _file.destroy();
1889                         }
1890                         elmName.firstChild.data = _artistFile.getName();
1891                         _artistFile.destroy();
1892                 }
1893         }
1894         
1895         function onFadeout(){
1896                 while( ICON_ARRAY.length > 0 ){
1897                         ICON_ARRAY.shift().destroy();
1898                 }
1899                 onUpdateFunction !== null && onUpdateData !== null && onUpdateFunction( onUpdateData );
1900                 onUpdateFunction = onUpdateData = null;
1901         }
1902         
1903         /* grobal method */
1904         // this.rootElement = elmWrap;
1905         this.displayName = 'premiumStage';
1906         this.ID          = 'premiumStage';
1907         this.rootElement = elmWrap;
1908         this.MIN_WIDTH   = 320;
1909         this.MIN_HEIGHT  = 320;
1910         this.init = function(){
1911                 jqContainer = $( elmContainer ).mousewheel( onMouseWheel );
1912                 
1913                 // よくない! 一時的な処理,,,
1914                 //var tree = pettanr.driver.createPictureTree();
1915                 //tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, drawIcons );
1916                 
1917                 delete instance.init;
1918         }
1919         this.onOpen = function( _windowW, _windowH, _ARTISTIDorFILE, _onUpdateFunction ){
1920                 instance.init && instance.init();
1921                 
1922                 if( pettanr.driver.isPettanrFileInstance( _ARTISTIDorFILE ) === true ){
1923                         var _data = pettanr.driver._getAPI().getFileData( _ARTISTIDorFILE );
1924                         if( _ARTISTIDorFILE.getType() === pettanr.driver.FILE_TYPE.ARTIST || pettanr.driver._getMyPicturesData() === _data ){
1925                                 artistID = _data.id || -1;
1926                         }
1927                 } else
1928                 if( Type.isNumber( _ARTISTIDorFILE ) === true ){
1929                         artistID = _ARTISTIDorFILE;
1930                 }
1931                 
1932                 onUpdateFunction = _onUpdateFunction || null;
1933                 onUpdateData = null;
1934                 
1935                 drawIcons();
1936                 
1937                 wrapX = 0;
1938                 containerW = ICON_ARRAY.length * itemW;
1939                 
1940                 winW = _windowW;
1941                 winH = _windowH;
1942                 var w = winW > containerW ? winW : containerW,
1943                         h = _windowH > containerH ? containerH : _windowH,
1944                         MATH_FLOOR = Math.floor;
1945                 
1946                 jqContainer.css( {
1947                         width:          w,
1948                         height:         0,
1949                         left:           0,
1950                         top:            MATH_FLOOR( _windowH /2)
1951                 }).stop().animate( {
1952                         height:         h,
1953                         top:            MATH_FLOOR( _windowH /2 -h /2)
1954                 }, onEnterShowImage );
1955                 
1956                 elmButton.style.cssText = [
1957                         'left:', MATH_FLOOR( winW /2 - buttonW /2), 'px;',
1958                         'top:', MATH_FLOOR( _windowH /2 + containerH /2 +10), 'px'
1959                 ].join('');
1960         }
1961         this.onPaneResize = function( _windowW, _windowH ){
1962                 var w = _windowW > containerW ? _windowW : containerW,
1963                         h = _windowH > containerH ? containerH : _windowH,
1964                         MATH_FLOOR = Math.floor,
1965                         offsetW = MATH_FLOOR( _windowW /2 -winW /2);
1966                         
1967                 winW = _windowW;
1968                 winH = _windowH;
1969                 if( offsetW <= 0){ // smaller
1970                         jqContainer.css( {
1971                                 left:                           offsetW,
1972                                 width:                          w
1973                         }).animate( {
1974                                 left:                           0,
1975                                 top:                            MATH_FLOOR( _windowH /2 -h /2)
1976                         });                                     
1977                 } else {
1978                         jqContainer.css( { // bigger
1979                                 left:                           0,
1980                                 width:                          w,
1981                                 borderLeftWidth:        offsetW
1982                         }).animate( {
1983                                 top:                            MATH_FLOOR( _windowH /2 -h /2),
1984                                 borderLeftWidth:        0
1985                         });
1986                 }
1987                 elmButton.style.cssText = [
1988                         'left:', MATH_FLOOR( _windowW /2 -buttonW /2), 'px;',
1989                         'top:', MATH_FLOOR( _windowH /2 +containerH /2 +10), 'px'
1990                 ].join('');
1991                 onEnterShowImage();
1992         }
1993         this.onClose = function(){
1994                 jqContainer.stop().animate( {
1995                                 height: 0,
1996                                 top:    Math.floor( winH /2 )
1997                         }, onFadeout );
1998                 onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1999                 onEnterInterval = null;
2000         }
2001 });
2002
2003
2004 /* ----------------------------------------
2005  * Text Editor
2006  *  - overlay
2007  */
2008 pettanr.textEditor = pettanr.view.registerApplication( function(){
2009         var jqWrap, jqTextarea, jqButton,
2010                 textElement, onUpdateFunction,
2011                 ID = 'textEditor',
2012                 panelX, panelY,
2013                 instance = this;
2014         //pettanr.key.addKeyDownEvent( ID, 69, false, false, clickOK);
2015         
2016         function clickOK(){
2017                 textElement && textElement.text( jqTextarea.val() );
2018                 onUpdateFunction ? window.setTimeout( asyncCallback, 50 ) : pettanr.textEditor.shutdown();
2019         }
2020         
2021         function asyncCallback(){
2022                 onUpdateFunction( textElement );
2023                 pettanr.textEditor.shutdown();
2024         }
2025         
2026         function keyCancel( e ){
2027                 if( e.keyCode === 69 && e.shiftKey === false && e.ctrlKey === true){
2028                         clickOK();
2029                         e.preventDefault();
2030                 e.keyCode = 0;
2031                 e.cancelBubble = true;
2032                 e.returnValue = false;
2033                         return false;
2034                 }       
2035         }
2036         function textareaFitHeight(){
2037                 var rows = 0;
2038                 while( jqTextarea.height() < textElement.h ){
2039                         rows++;
2040                         jqTextarea.attr( 'rows', rows );
2041                 }
2042                 rows > 1 && jqTextarea.attr( 'rows', --rows );
2043         }
2044         
2045         /* grobal method */
2046         // this.rootElement = elmWrap;
2047         this.displayName = 'textEditor';
2048         this.ID          = 'textEditor';
2049         this.rootElement = document.getElementById( 'speach-editor-wrapper' );
2050         this.MIN_WIDTH   = 320;
2051         this.MIN_HEIGHT  = 320;
2052         this.init = function(){
2053                 jqWrap     = $( '#speach-editor-wrapper' ).hide();
2054                 jqTextarea = $( '#speach-editor' ).keydown( keyCancel );
2055                 jqButton   = $( '#speach-edit-complete-button').click( clickOK );
2056                 delete instance.init;
2057         }
2058         this.onOpen = function( _w, _h, _panelX, _panelY, _textElement, _onUpdateFunction ){
2059                 instance.init && instance.init();
2060                 
2061                 panelX = _panelX;
2062                 panelY = _panelY;
2063                 textElement = _textElement;
2064                 onUpdateFunction = _onUpdateFunction || null;
2065                 
2066                 jqWrap.show();
2067                 instance.onPaneResize( _w, _h );
2068                 jqTextarea.val( _textElement.text() ).focus();
2069                 
2070                 /*
2071                  * ie6,7は、textarea { width:100%}でも高さが変わらない。rowsを設定。
2072                  */
2073                 pettanr.ua.isIE === true && pettanr.ua.ieVersion <= 7 && setTimeout( textareaFitHeight, 0);
2074         }
2075         this.onPaneResize = function( _w, _h ){
2076                 jqWrap.css( {
2077                         left:                   textElement.x + panelX,
2078                         top:                    textElement.y + panelY,
2079                         width:                  textElement.w,
2080                         height:                 textElement.h
2081                 });
2082         }
2083         this.onClose = function(){
2084                 jqWrap.hide();
2085                 textElement = onUpdateFunction = null;
2086         }
2087 });
2088
2089 // i18n
2090 // login
2091 // lib
2092
2093 pettanr.fn( pettanr.view);
2094 pettanr.fn( pettanr.overlay);
2095 pettanr.fn( pettanr.key);
2096 pettanr.fn( pettanr.balloon);
2097
2098 pettanr.fn( pettanr.editor);
2099
2100 pettanr.fn( pettanr.file);
2101 pettanr.fn( pettanr.finder);
2102 pettanr.fn( pettanr.gallery);
2103 pettanr.fn( pettanr.cabinet);
2104
2105 $(window).ready( pettanr.init);