OSDN Git Service

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