OSDN Git Service

client is version0.4.21, brush up around boot application.
[pettanr/pettanr.git] / public / assets / system.js
1 /*
2  * pettanR system.js
3  *   version 0.4.21
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                 getChildFileByIndex: function( _index ){
392                         var _access = FILE_CONTROLER.getFileDataAccess( this ),
393                                 _children = FILE_CONTROLER.getChildren( this );
394                         if( typeof _index !== 'number' || _index < 0 || Type.isArray( _children ) === false || _index >= _children.length) return null;
395                         var _file = new FileClass( _access.TREE, _access.DATA, _children[ _index ]);
396                         // _file.init();
397                         return _file;
398                 },
399                 getName: function(){
400                         var driver = FILE_CONTROLER.getDriver( this );
401                         if( typeof driver.getName === 'function'){
402                                 return driver.getName( this );
403                         }
404                         return FileDriverBase.getName( this);
405                 },
406                 getThumbnail: function(){
407                         var driver = FILE_CONTROLER.getDriver( this);
408                         if( typeof driver.getThumbnail === 'function'){
409                                 return driver.getThumbnail( this);
410                         }
411                         return FileDriverBase.getThumbnail( this);
412                 },
413                 getType: function(){
414                         var _data = FILE_CONTROLER.getFileData( this);
415                         return typeof _data.type === 'number' ? _data.type : pettanr.file.FILE_TYPE.UNKNOWN;
416                 },
417                 getState: function(){
418                         var _data = FILE_CONTROLER.getFileData( this);
419                         return typeof _data.state === 'number' ? _data.state : pettanr.file.FILE_STATE.OK;
420                 },
421                 getSummary: function(){
422                         var driver = FILE_CONTROLER.getDriver( this );
423                         if( typeof driver.getSummary === 'function'){
424                                 return driver.getSummary( this );
425                         }
426                         return FileDriverBase.getSummary( this);
427                 },
428                 isWritable: function(){
429                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.WRITE );
430                 },
431                 isSortable: function(){
432                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.SORT );
433                 },              
434                 isCreatable: function(){
435                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.CREATE );
436                 },
437                 isRenamable: function(){
438                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.RENAME );
439                 },
440                 isDeletable: function(){
441                         return FILE_CONTROLER.getUpdateFlag( this, pettanr.file.FILE_UPDATE_POLICY.DELETE );
442                 },
443                 read: function(){
444                         // simpleDeepCopy
445                         var driver = FILE_CONTROLER.getDriver( this );
446                         if( typeof driver.read === 'function'){
447                                 return driver.read( this );
448                         }
449                         return FileDriverBase.read( this );
450                 },
451                 write: function( _newData, _onUpdateFunction ){
452                         var driver = FILE_CONTROLER.getDriver( this );
453                         if( typeof driver.write === 'function'){
454                                 return driver.write( this, _newData, _onUpdateFunction );
455                         }
456                         return FileDriverBase.write( this, _newData, _onUpdateFunction );
457                 },
458                 viewerApplicationList: function(){
459                         var driver = FILE_CONTROLER.getDriver( this );
460                         if( typeof driver.viewerApplicationList === 'function'){
461                                 return driver.viewerApplicationList( this );
462                         }
463                         return FileDriverBase.viewerApplicationList( this );
464                 },
465                 editorApplicationList: function(){
466                         var driver = FILE_CONTROLER.getDriver( this );
467                         if( typeof driver.editorApplicationList === 'function'){
468                                 return driver.editorApplicationList( this );
469                         }
470                         return FileDriverBase.viwerApps( this );
471                 },
472                 create: function(){
473                         
474                 },
475                 sort: function(){
476                         
477                 },
478                 onCopy: function(){
479                         
480                 },
481                 onDelete: function(){
482                         
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                 ELM_CONTAINER.appendChild( elmContainer );
982                 
983                 function draw( _w, _h ){
984                         w = Type.isFinite( _w ) === true ? _w : w;
985                         h = Type.isFinite( _h ) === true ? _h : h;
986                         bodyH = h - headH;
987                         var     l = tree.hierarchy() +1,
988                                 m = BREAD_ARRAY.length,
989                                 _file, _bread;
990                         for(var i=0; i<l; ++i){
991                                 _file = i !== l-1 ? tree.getParentFileAt( i) : tree.getCurrentFile();
992                                 if( i < m){
993                                         BREAD_ARRAY[ i].init( _file, elmLocation, i, onHeadClick);
994                                 } else {
995                                         BREAD_ARRAY.push( getBreadcrumb( _file, elmLocation, i, onHeadClick ));
996                                 }
997                         }
998                         while( l < BREAD_ARRAY.length){
999                                 BREAD_ARRAY.pop().destroy();
1000                         }
1001                         
1002                         l = _file.getChildFileLength();
1003                         m = ICON_ARRAY.length;
1004
1005                         for( i=0; i<l; ++i){
1006                                 if( i < m){
1007                                         ICON_ARRAY[ i ].init( _file.getChildFileByIndex( i), elmBody, w, i, style, onDown, onEditor, onViwer, onAction );
1008                                 } else {
1009                                         ICON_ARRAY.push( getFinderIcon( _file.getChildFileByIndex( i), elmBody, _w, i, style, onDown, onEditor, onViwer, onAction ));
1010                                 }
1011                         }
1012                         if( _file.getState() === pettanr.file.FILE_STATE.LOADING ){
1013                                 elmBody.className = 'finder-body loading';
1014                         } else {
1015                                 elmBody.className = 'finder-body';
1016                         }
1017                         elmBody.style.height = bodyH + 'px';
1018                         
1019                         while( l < ICON_ARRAY.length){
1020                                 ICON_ARRAY.pop().destroy();
1021                         }
1022                 }
1023                 
1024                 function onHeadClick( i){
1025                         var l = BREAD_ARRAY.length -1;
1026                         if( i < l){
1027                                 var _file = tree.getParentFileAt( i);
1028                                 if( _file !== null){
1029                                         tree.up( i);
1030                                         draw( w, h );
1031                                 }
1032                         }
1033                 }
1034                 function onDown( i ){
1035                         if( i < ICON_ARRAY.length ){
1036                                 var _file = tree.getCurrentFile().getChildFileByIndex( i );
1037                                 if( _file !== null && ( _file.getChildFileLength() !== -1 || _file.getType() === pettanr.file.FILE_TYPE.FOLDER)){
1038                                         tree.down( i );
1039                                         draw( w, h );
1040                                 }
1041                         }
1042                 }
1043                 function onEditor( _file, _app ){
1044                         _app.boot( _file );
1045                 }
1046                 function onViwer( _file, _app ){
1047                         _app.bootInOverlay( _file );
1048                 }
1049                 function onAction( _file ){
1050
1051                 }
1052                 this.rootElement = elmContainer;
1053                 this.parentElement = ELM_CONTAINER;
1054                 this.displayName = 'finder';
1055                 this.ID = 'finder';
1056                 this.MIN_WIDTH = 240;
1057                 this.MIN_HEIGHT = 240;
1058                 this.init = function(){
1059                         //$( elmLocation).click( onHeadClick);
1060                         //$( elmContainer).click( onBodyClick);
1061                         var position = pettanr.util.getAbsolutePosition( elmLocation );
1062                         headX = position.x;
1063                         headY = position.y;
1064                         bodyY = pettanr.util.getAbsolutePosition( elmBody ).y;
1065                         delete instance.init;
1066                 }
1067                 this.onPaneResize = function( _w, _h ){
1068                         instance.init && instance.init();
1069                         draw( _w, _h );                 
1070                         
1071                         w = _w;
1072                         h = _h;
1073                         elmBody.style.height = ( _h - headH ) + 'px';
1074                         
1075                         for(var i=0, l=ICON_ARRAY.length; i<l; ++i){
1076                                 ICON_ARRAY[ i].onResize( _w );
1077                         }
1078                 }
1079         }
1080         FinderClass.prototype = pettanr.view._getAbstractApplication();
1081         
1082         function getFinderIcon( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction){
1083                 var _icon;
1084                 if( FINDER_ICON_POOL.length > 0){
1085                         _icon = FINDER_ICON_POOL.shift();
1086                 } else {
1087                         _icon = new FinderIconClass();
1088                 }
1089                 _icon.init( _file, _elmContainer, w, index, style, onDown, onEditor, onViwer, onAction );
1090                 return _icon;
1091         }
1092         
1093         function getBreadcrumb( _file, _elmContainer, index, callback){
1094                 var _bread;
1095                 if( BREAD_OBJECT_POOL.length > 0){
1096                         _bread = BREAD_OBJECT_POOL.shift();
1097                 } else {
1098                         _bread = new BreadcrumbClass();
1099                 }
1100                 _bread.init( _file, _elmContainer, index, callback);
1101                 return _bread;
1102         }
1103
1104         return {
1105                 init: function(){
1106                         
1107                 },
1108                 createFinder: function( _applicationReference, _elmTarget, _tree, _header, _footer ){
1109                         if( pettanr.view.isApplicationReference( _applicationReference ) === false ) return;
1110                         
1111                         var _finder = new FinderClass( _elmTarget, _tree, _header, _footer );
1112                         FINDER_ARRAY.push( _finder );
1113                         return _finder;
1114                 },
1115                 registerFinderHead: function(){
1116                         
1117                 },
1118                 registerFinderPane: function( _finderPane){
1119                         
1120                 },
1121                 isFinderInstance: function( _finder){
1122                         return _finder instanceof FinderClass;
1123                 },
1124                 isFinderPaneInstance: function(){
1125                         
1126                 },
1127                 isFinderHeadInstance: function(){
1128                 }
1129         }
1130 })();
1131
1132
1133 pettanr.driver = ( function(){
1134         var MyAuthorID = 'current_author' in window ? current_author.id : ( pettanr.DEBUG ? 1 : -1 ),
1135                 MyArtistID = 'current_artist' in window ? current_artist.id : ( pettanr.DEBUG ? 1 : -1 ),
1136                 Driver = {
1137                         getSeqentialFiles: function( _file){
1138                                 var _data = FileAPI.getFileData( _file),
1139                                         _json = _data !== null ? _data.json : null;
1140                                 if( _json === true && _data.type === pettanr.driver.FILE_TYPE.COMIC ){
1141                                         if( pettanr.LOCAL === true ){
1142                                                 _json = [ 'json\/comics_', _data.id, '.json' ].join( '' );
1143                                         } else {
1144                                                 _json = [ pettanr.CONST.PETTANR_ROOT_PATH, 'comics\/', _data.id, '.json\/play\/' ].join( '' );
1145                                         }
1146                                 }
1147                                 if( typeof _json === 'string'){
1148                                         FileAPI.getJson( _file, _json, onLoadJson, onErrorJson);
1149                                         _data.state = pettanr.file.FILE_STATE.LOADING;
1150                                         _data.json = null;
1151                                         return;
1152                                 }
1153                         },
1154                         getName: function( _file){
1155                                 var _data = FileAPI.getFileData( _file),
1156                                         _type = _data !== null ? _data.type : null;
1157                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
1158                                         return [ _data.id, _data.ext ].join( '.');
1159                                 } else
1160                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1161                                         return [ _data.t, ':', _data.comic.title ].join( '');
1162                                 } else
1163                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1164                                         return _data.title;
1165                                 } else
1166                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
1167                                         return [ _data.id , ':', _data.name, '画伯' ].join( '');
1168                                 } else
1169                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR ){
1170                                         return [ _data.id , ':', _data.name, '先生' ].join( '');
1171                                 }
1172                                 return _data.name;
1173                         },
1174                         getThumbnail: function( _file){
1175                                 var _data = FileAPI.getFileData( _file),
1176                                         _type = _data !== null ? _data.type : null;
1177                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1178                                         return { image: [ pettanr.CONST.RESOURCE_PICTURE_PATH, 'thumbnail/', _data.id, '.', _data.ext ].join( '')};
1179                                 }
1180                                 if( _data === FILE_DATA_COMICS_ROOT){
1181                                         return { className: 'file-type-cabinet'};
1182                                 }
1183                                 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1184                                         return { className: 'file-type-comic'};
1185                                 }
1186                                 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1187                                         return { className: 'file-type-panel'};
1188                                 }
1189                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1190                                         return { className: 'file-type-author'};
1191                                 }
1192                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1193                                         return { className: 'file-type-artist'};
1194                                 }
1195                                 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1196                                         return { className: 'file-type-folder'};
1197                                 }
1198                                 return { className: 'file-type-broken'};
1199                         },
1200                         getSummary: function( _file ){
1201                                 var _data = FileAPI.getFileData( _file),
1202                                         _type = _data !== null ? _data.type : null;
1203                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE){
1204                                         return [ _data.width, 'x', _data.height, ', filesize:', _data.filesize, ', lisence:', _data.license ].join( '' );
1205                                 }
1206                                 if( _data === FILE_DATA_COMICS_ROOT){
1207                                         return 'cabinet file';
1208                                 }
1209                                 if( _type === pettanr.driver.FILE_TYPE.COMIC){
1210                                         return 'comic file';
1211                                 }
1212                                 if( _type === pettanr.driver.FILE_TYPE.PANEL){
1213                                         return [ _data.width, 'x', _data.height ].join( '' );
1214                                 }
1215                                 if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
1216                                         return 'author file';
1217                                 }
1218                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST){
1219                                         return [ 'Email:', _data.email || 'empty' , ', HP:', _data.homepage_url || 'empty' ].join( '' );
1220                                 }
1221                                 if( _type === pettanr.file.FILE_TYPE.FOLDER){
1222                                         return 'pettanR folder';
1223                                 }
1224                                 return 'pettanR unknown file';
1225                         },
1226                         write: function( _file, _newData, _onUpdateFunction ){
1227                                 var _data = FileAPI.getFileData( _file ),
1228                                         _type = _data !== null ? _data.type : null;
1229                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1230                                 }
1231                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1232                                 }
1233                                 if( _type === pettanr.driver.FILE_TYPE.PANEL_PICTURE ){
1234                                         
1235                                 }
1236                                 if( _type === pettanr.driver.FILE_TYPE.BALLOON ){
1237                                 }
1238                                 if( _type === pettanr.driver.FILE_TYPE.PICTURE ){
1239                                 }                               
1240                         },
1241                         viewerApplicationList: function( _file ){
1242                                 var _data = FileAPI.getFileData( _file ),
1243                                         _type = _data !== null ? _data.type : null;
1244                                         
1245                                 if( _data === FILE_DATA_MY_PICTURES_ROOT ){
1246                                         return [ pettanr.premiumSatge ];
1247                                 }
1248                                 if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
1249                                         return [ pettanr.premiumSatge ];
1250                                 }
1251                                 return [];
1252                         },
1253                         editorApplicationList: function( _file ){
1254                                 var _data = FileAPI.getFileData( _file ),
1255                                         _type = _data !== null ? _data.type : null;
1256                                 if( _type === pettanr.driver.FILE_TYPE.PANEL ){
1257                                         return [ pettanr.editor ];
1258                                 }
1259                                 if( _type === pettanr.driver.FILE_TYPE.COMIC ){
1260                                         return [ pettanr.editor, pettanr.comicConsole ];
1261                                 }
1262                                 return [];
1263                         }
1264                 },
1265                 FileAPI = pettanr.file.registerDriver( Driver ),
1266                 FILE_DATA_SERVICE_ROOT = {
1267                         name:           'PettanR root',
1268                         type:           pettanr.file.FILE_TYPE.FOLDER,
1269                         children:       []
1270                 },
1271                 FILE_DATA_COMICS_ROOT = {
1272                         name:           'Comics',
1273                         type:           pettanr.file.FILE_TYPE.FOLDER,
1274                         children:       [],
1275                         driver:         Driver,
1276                         json:           pettanr.CONST.URL_COMICS_JSON
1277                 },
1278                 FILE_DATA_PANELS_ROOT = {
1279                         name:           'Panels',
1280                         type:           pettanr.file.FILE_TYPE.FOLDER,
1281                         children:       [],
1282                         driver:         Driver,
1283                         json:           pettanr.CONST.URL_PANELS_JSON
1284                 },
1285                 FILE_DATA_PICTURE_ROOT = {
1286                         name:           'Picutures',
1287                         type:           pettanr.file.FILE_TYPE.FOLDER,
1288                         children:       [],
1289                         driver:         Driver,
1290                         json:           pettanr.CONST.URL_RESOURCE_PICTURES_JSON
1291                 },
1292                 FILE_DATA_MY_COMICS_ROOT = {
1293                         name:           'My Comics',
1294                         type:           pettanr.file.FILE_TYPE.FOLDER,
1295                         children:       [],
1296                         driver:         Driver,
1297                         id:                     MyAuthorID
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                         id:                     MyArtistID
1311                 },
1312                 FILE_DATA_AUTHOR_ROOT = {
1313                         name:           'Authors',
1314                         type:           pettanr.file.FILE_TYPE.FOLDER,
1315                         children:       []
1316                 },
1317                 FILE_DATA_ARTIST_ROOT = {
1318                         name:           'Artists',
1319                         type:           pettanr.file.FILE_TYPE.FOLDER,
1320                         children:       []
1321                 },
1322                 FILE_DATA_LISENCE_ROOT = {
1323                         name:           'Original Lisences',
1324                         type:           pettanr.file.FILE_TYPE.FOLDER,
1325                         children:       []
1326                 },
1327                 FILE_DATA_BALLOON_ROOT = {
1328                         name:           'Balloon templetes',
1329                         type:           pettanr.file.FILE_TYPE.FOLDER,
1330                         children:       []
1331                 },
1332                 AUTHOR_ARRAY = [],
1333                 ARTIST_ARRAY = [],
1334                 PANEL_ARRAY = [],
1335                 COMIC_ARRAY = [],
1336                 RESOURCE_PICTURE_ARRAY = [],
1337                 BALLOON_TEMPLETE_ARRAY = [],
1338                 ORIGINAL_LICENSE_ARRAY = [],
1339                 BASIC_LICENSES = 'cc_by,cc_nc,cc_nd,cc_sa,keep_aspect_ratio,no_convert,no_flip,no_resize'.split( ',');
1340         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);
1341         FILE_DATA_COMICS_ROOT.children.push( FILE_DATA_MY_COMICS_ROOT, FILE_DATA_LATEST_COMICS, FILE_DATA_AUTHOR_ROOT);
1342         FILE_DATA_PICTURE_ROOT.children.push( FILE_DATA_MY_PICTURES_ROOT, FILE_DATA_ARTIST_ROOT);
1343         
1344         FileAPI.createFolderUnderRoot( FILE_DATA_SERVICE_ROOT);
1345
1346         function onLoadJson( _file, _json ){
1347                 var _access = FileAPI.getFileDataAccess( _file),
1348                         _data = _access !== null ? _access.DATA : null,
1349                         l;
1350                 if( _data === null){
1351                         onErrorJson( _file);
1352                         return;
1353                 }
1354                 _data.state = pettanr.file.FILE_STATE.OK;
1355                 
1356                 if( Type.isArray( _json ) === true ){
1357                         l = _json.length;
1358                         if( l === 0) return;
1359                         for( var i=0; i<l; ++i ){
1360                                 buildFileData( _json[ i], _data);
1361                         }                       
1362                 } else
1363                 if( _json.id ){
1364                         buildFileData( _json, _data );
1365                 }
1366                 _access.dispatchFileEvent( FileAPI.createFileEvent( pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES, _file, 'children', null));
1367         }
1368         function onErrorJson( _file ){ 
1369                 var _data = FileAPI.getFileData( _file);
1370                 if( _data !== null){
1371                         _data.state = pettanr.file.FILE_STATE.ERROR;
1372                 }
1373         }
1374         function buildFileData( _data, _parent ){
1375                 var _array, i, l;
1376                 // Panel
1377                 if( _parent === FILE_DATA_PANELS_ROOT ){
1378                         _data.type = pettanr.driver.FILE_TYPE.PANEL;
1379                         _array = PANEL_ARRAY;
1380                 } else
1381                 // Comic
1382                 if( _parent === FILE_DATA_COMICS_ROOT ){
1383                         _data.type = pettanr.driver.FILE_TYPE.COMIC;
1384                         _array = COMIC_ARRAY;
1385                 } else
1386                 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC ){
1387                         _array = COMIC_ARRAY;
1388                 } else
1389                 // Lisence
1390                 if( _parent === FILE_DATA_LISENCE_ROOT ){
1391                         _data.type = pettanr.driver.FILE_TYPE.LICENSE;
1392                         _array = ORIGINAL_LICENSE_ARRAY;
1393                 } else
1394                 // Author
1395                 if( _parent === FILE_DATA_AUTHOR_ROOT ){
1396                         _data.type = pettanr.driver.FILE_TYPE.AUTHOR;
1397                         _array = AUTHOR_ARRAY;
1398                 } else
1399                 // Artist
1400                 if( _parent === FILE_DATA_ARTIST_ROOT ){
1401                         _data.type = pettanr.driver.FILE_TYPE.ARTIST;
1402                         _array = ARTIST_ARRAY;
1403                 } else          
1404                 // Picture
1405                 if( _parent === FILE_DATA_PICTURE_ROOT || _parent === FILE_DATA_MY_PICTURES_ROOT ){
1406                         _data.type = pettanr.driver.FILE_TYPE.PICTURE;
1407                         _array = RESOURCE_PICTURE_ARRAY;
1408                         // original_license を含まなければ、license object を削除して ビットデータ で保持
1409                         // original_license なら ファイルを作る buildFileData( _license, FILE_DATA_LISENCE_ROOT)
1410                         var _license = _data.license,
1411                                 _rule,
1412                                 _Math_pow = Math.pow,
1413                                 _bits = 0;
1414                         if( typeof _license === 'object'){
1415                                 for( i=0, l=BASIC_LICENSES.length; i<l; ++i){
1416                                         _rule = _license[ BASIC_LICENSES[ i]]
1417                                         if( typeof _rule === 'number' && _rule === 1 ){
1418                                                 _bits += _Math_pow( 2, i);
1419                                         }
1420                                 }
1421                                 _data.license = _bits;
1422                         }
1423                 } else {
1424                         alert( 'error' );
1425                 }
1426                 
1427                 _data.driver = Driver;
1428                 
1429                 // _array に _data を格納 または 上書き
1430                 if( typeof _data.id === 'number' && _data.id > 0 ){
1431                         var _id = _data.id - 1,
1432                                 __data = _array[ _id ],
1433                                 _reserved = pettanr.file.FILE_DATA_PROPERTY_RESERVED.join( ', ' );
1434                         if( __data ){
1435                                 for( var key in _data){
1436                                         if( _reserved.indexOf( key ) === -1 ){
1437                                                 __data[ key ] = _data[ key ];
1438                                         }
1439                                 }
1440                                 _data = __data; // このタイミングで参照が切れるので注意!!
1441                         } else {
1442                                 _array[ _id ] = _data;
1443                         }
1444                 } else {
1445                         alert( 'error' );
1446                 }
1447
1448                 // Author
1449                 // Artist
1450                 if( _parent === FILE_DATA_AUTHOR_ROOT || _parent === FILE_DATA_ARTIST_ROOT ){
1451                         addChildData( _parent, _data );
1452                 } else
1453                 // Comic + Panels
1454                 if( _parent.type === pettanr.driver.FILE_TYPE.COMIC || _parent === FILE_DATA_COMICS_ROOT ){
1455                         var _panels = _data.panels,
1456                                 _panel;
1457                         if( _panels && Type.isArray( _panels ) === true ){
1458                                 
1459                                 for( i=0, l=_panels.length; i<l; ++i){
1460                                         _panel = buildFileData( _panels[ i ], FILE_DATA_PANELS_ROOT );
1461                                         /*
1462                                          * 間違い! t 順に格納
1463                                          */
1464                                         addChildData( _data, _panel );
1465                                 }
1466                                 delete _data.panels;
1467                         } else {
1468                                 if( _data.json !== null ){
1469                                         _data.json = true;
1470                                 }
1471                                 if( Type.isArray( _data.children ) === false ){
1472                                         _data.children = [];
1473                                 }                               
1474                         }
1475                         var _author = _data.author || getResource( AUTHOR_ARRAY, _data.author_id );
1476                         if( _author ){
1477                                 _data.author = _author = buildFileData( _author, FILE_DATA_AUTHOR_ROOT );
1478                                 addChildData( _author, _data );
1479                                 _author.id === MyAuthorID && addChildData( FILE_DATA_MY_COMICS_ROOT, _data );
1480                         }
1481                         if( _parent === FILE_DATA_COMICS_ROOT ){
1482                                 addChildData( FILE_DATA_LATEST_COMICS, _data);
1483                         }
1484                 } else
1485                 // Panel
1486                 if( _parent === FILE_DATA_PANELS_ROOT ){
1487                         _data.comic = getResource( COMIC_ARRAY, _data.comic_id );
1488                         _data.author = getResource( AUTHOR_ARRAY, _data.author_id );
1489
1490                         // picture data をファイルに取り出し
1491                         var _elements = _data.panel_elements,
1492                                 _elm;
1493                         if( Type.isArray( _elements ) === true ){
1494                                 for( i=0, l=_elements.length; i<l; ++i){
1495                                         _elm = _elements[ i];
1496                                         if( _elm.resource_picture ){
1497                                                 _elm.resource_picture = buildFileData( _elm.resource_picture, FILE_DATA_PICTURE_ROOT ); // 上記参照切れに備えてここで上書き
1498                                         } else {
1499                                                 _elm.resource_picture = getResource( RESOURCE_PICTURE_ARRAY, _elm.resource_picture_id );
1500                                         }
1501                                 }                               
1502                         }
1503                 } else
1504                 // Picture
1505                 if( _data.type == pettanr.driver.FILE_TYPE.PICTURE ){
1506                         var _artist = _data.artist || getResource( ARTIST_ARRAY, _data.artist_id );
1507                         if( _artist){
1508                                 _data.artist = _artist = buildFileData( _artist, FILE_DATA_ARTIST_ROOT );
1509                                 addChildData( _artist, _data );
1510                                 if( _artist.id === MyArtistID ){
1511                                         addChildData( FILE_DATA_MY_PICTURES_ROOT, _data );
1512                                         //FILE_DATA_MY_PICTURES_ROOT.type = pettanr.driver.FILE_TYPE.ARTIST;
1513                                         //FILE_DATA_MY_PICTURES_ROOT.id = MyArtistID;
1514                                 }
1515                         }
1516                 }
1517                 return _data;
1518         }
1519         function addChildData( _parent, _child ){
1520                 if( Type.isArray( _parent.children ) === false){
1521                         _parent.children = [];
1522                 }
1523                 pettanr.util.getIndex( _parent.children, _child ) === -1 && _parent.children.push( _child );
1524         }
1525         function getResource( _array, _id ){
1526                 if( Type.isArray( _array ) === false || Type.isNumber( _id ) === false || _id < 1 ) return null;
1527                 var _data = _array[ _id - 1 ];
1528                 if( !_data ){
1529                         _data = _array[ _id - 1 ] = {};
1530                 }
1531                 return _data;
1532         }
1533
1534         return {
1535                 createComicTree: function(){
1536                         return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT ); //FILE_DATA_COMICS_ROOT);
1537                 },
1538                 createPictureTree: function(){
1539                         return pettanr.file.createTree( FILE_DATA_PICTURE_ROOT );
1540                 },
1541                 createArtistTree: function(){
1542                         return pettanr.file.createTree( FILE_DATA_ARTIST_ROOT );
1543                 },
1544                 createServiceTree: function(){
1545                         return pettanr.file.createTree( FILE_DATA_SERVICE_ROOT );
1546                 },
1547                 isPettanrFileInstance: function( _file ){
1548                         if( pettanr.file.isFileInstance( _file ) === true){
1549                                 var _data = FileAPI.getFileData( _file);
1550                                 return _data !== null && _data.driver === Driver;
1551                         }
1552                         return false;
1553                 },
1554                 _getAPI: function(){
1555                         return FileAPI;
1556                 },
1557                 _getMyPicturesData: function(){
1558                         return FILE_DATA_MY_PICTURES_ROOT;
1559                 },
1560                 FILE_TYPE: {
1561                         COMIC:                          FileAPI.createFileTypeID(),
1562                         PANEL:                          FileAPI.createFileTypeID(),
1563                         PICTURE:                        FileAPI.createFileTypeID(),
1564                         PANEL_PICTURE:          FileAPI.createFileTypeID(),
1565                         BALLOON:                        FileAPI.createFileTypeID(),
1566                         AUTHOR:                         FileAPI.createFileTypeID(),
1567                         ARTIST:                         FileAPI.createFileTypeID(),
1568                         LICENSE:                        FileAPI.createFileTypeID()
1569                 }
1570         }
1571 })();
1572
1573 pettanr.entrance = pettanr.view.registerApplication( function(){
1574         this.displayName = 'Home';
1575         this.ID          = 'Home';
1576         this.rootElement = document.getElementById('entrance');
1577         this.onOpen = function( _w, _h, _option ){
1578                 var pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height;
1579                 document.getElementById('inner-wrapper').style.height = ( _h - pageHeaderH ) + 'px';
1580         }
1581         this.onClose = function(){
1582                 document.getElementById('inner-wrapper').style.height = '0px';
1583         }
1584         this.onPaneResize = function( _w, _h){
1585                 this.onOpen( _w, _h );
1586         }
1587 });
1588 pettanr.entrance.addToLancher();
1589
1590 pettanr.cabinet = pettanr.view.registerApplication( function(){
1591         var finder,
1592                 elmContainer = document.getElementById( 'cabinet'),
1593                 option,
1594                 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height;
1595                 
1596         this.displayName = 'Comic list';
1597         this.ID          = 'Comiclist';
1598         this.rootElement = elmContainer;
1599         this.onOpen = function( _w, _h ){
1600                 finder = finder || pettanr.finder.createFinder( pettanr.cabinet, elmContainer, pettanr.driver.createComicTree() );
1601                 finder.resize( _w, _h - pageHeaderH );
1602         }
1603         this.onClose = function(){
1604                 // finder.close();
1605         }
1606         this.onPaneResize = function( _w, _h){
1607                 finder.resize( _w, _h - pageHeaderH );
1608         }
1609 });
1610 pettanr.cabinet.addToLancher();
1611
1612 pettanr.gallery = pettanr.view.registerApplication( function(){
1613         var finder,
1614                 elmContainer = document.getElementById( 'gallery' ),
1615                 option,
1616                 pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' ) ).height;
1617                 
1618         this.displayName = 'Pictures';
1619         this.ID          = 'pictures';
1620         this.rootElement = elmContainer;
1621         this.onOpen = function( _w, _h ){
1622                 finder = finder || pettanr.finder.createFinder( pettanr.gallery, elmContainer, pettanr.driver.createPictureTree() );
1623                 finder.resize( _w, _h - pageHeaderH );
1624         }
1625         this.onClose = function(){
1626                 // finder.close();
1627         }
1628         this.onPaneResize = function( _w, _h){
1629                 finder.resize( _w, _h - pageHeaderH );
1630         }
1631 });
1632 pettanr.gallery.addToLancher();
1633
1634 pettanr.backyard = pettanr.view.registerApplication( function(){
1635         this.displayName = 'Settings';
1636         this.ID          = 'Settinds';
1637         this.rootElement = document.getElementById( 'backyard' );
1638         this.onOpen = function( _w, _h, _option ){
1639         }
1640         this.onClose = function(){
1641         }
1642         this.onPaneResize = function( _w, _h){
1643         }
1644 });
1645 pettanr.backyard.addToLancher();
1646
1647 if( pettanr.DEBUG === true){
1648         pettanr.debug = pettanr.view.registerApplication( function(){
1649                 var elmDl = document.getElementById( 'useragent'),
1650                         elmDt, elmDd,
1651                         data = {
1652                                 pettanR:        pettanr.version,
1653                                 ua:                     navigator.userAgent,
1654                                 platform:       navigator.platform,
1655                                 appVersion:     navigator.appVersion,
1656                                 appCodeName:navigator.appCodeName,
1657                                 appName:        navigator.appName,
1658                                 language:       navigator.browserLanguage || navigator.language,
1659                                 ActiveX:        pettanr.ua.ACTIVEX
1660                         },
1661                         ua = pettanr.ua;
1662                 if( ua.IE){
1663                         //data.ua = 'Internet Explorer';
1664                         data.version = ua.IE;
1665                         if( ua.ieVersion >= 8) data.RenderingVersion = ua.ieRenderingVersion;
1666                         data.browserType = ua.STANDALONE === true ? 'Standalone' : 'bundle';
1667                         if( ua.ieVersion < 9) {
1668                                 data.vml = ua.VML;
1669                         } else {
1670                                 data.svg = ua.SVG;
1671                         }
1672                 }
1673                 data.RenderingMode = ua.isStanderdMode === true ? 'Standerd' : 'Quirks';
1674                 
1675                 for( var key in data){
1676                         elmDt = document.createElement( 'dt');
1677                         elmDt.innerHTML = key;
1678                         elmDd = document.createElement( 'dd');
1679                         elmDd.innerHTML = '' + data[ key];
1680                         if( !data[ key]) elmDd.style.color = 'red';
1681                         elmDl.appendChild( elmDt);
1682                         elmDl.appendChild( elmDd);
1683                 }
1684                 this.displayName = 'Debug';
1685                 this.ID          = 'debug';
1686                 this.rootElement = document.getElementById( 'debug' );
1687                 this.onOpen = function( _w, _h, _option ){
1688                         var pageHeaderH = pettanr.util.getElementSize( document.getElementById( 'header' )).height;
1689                         document.getElementById( 'inner-wrapper' ).style.height = ( _h - pageHeaderH ) + 'px';
1690                 }
1691                 this.onClose = function(){
1692                         document.getElementById( 'inner-wrapper' ).style.height = '0px';
1693                 }
1694                 this.onPaneResize = function( _w, _h ){
1695                         pettanr.debug.onOpen( _w, _h );
1696                 }
1697         });
1698         pettanr.debug.addToLancher();
1699         
1700 } else {
1701         var _debug = document.getElementById( 'debug');
1702         if( _debug){
1703                 pettanr.util.removeAllChildren( _debug);
1704                 _debug.parentNode.removeChild( _debug);
1705                 _debug = null;
1706         }
1707 }
1708
1709 /* ----------------------------------------
1710  * Image Group Exproler
1711  *  - overlay
1712  */
1713 pettanr.premiumSatge = pettanr.view.registerApplication( function(){
1714         var ICON_ARRAY = [],
1715                 WHEEL_DELTA = 64,
1716                 ARTIST_TREE = pettanr.driver.createArtistTree(),
1717                 ARTIST_ROOT_FILE = ARTIST_TREE.getRootFile(),
1718                 instance = this,
1719                 winW, winH,
1720                 wrapX,
1721                 elmWrap = document.getElementById( 'image-gruop-wrapper' ),
1722                 elmContainer = document.getElementById( 'image-icon-container' ),
1723                 containerW,
1724                 containerH = pettanr.util.getElementSize( elmContainer ).height,                
1725                 elmIconOrigin = ( function(){
1726                         var ret = document.createElement( 'div' ),
1727                                 data = document.createElement( 'div' );
1728                         ret.appendChild( data );
1729                         ret.className = 'image-gruop-item';
1730                         data.className = 'image-gruop-item-title';
1731                         return ret;
1732                 })(),
1733                 jqContainer,
1734                 size = pettanr.util.getElementSize( elmIconOrigin ),
1735                 itemW = size.width,
1736                 itemH = size.height,
1737                 elmName = document.getElementById( 'gruop-name-display' ),
1738                 elmButton = document.getElementById( 'image-gruop-button' ),
1739                 buttonW = pettanr.util.getElementSize( elmButton ).width,
1740                 //onUpdateFunction,
1741                 _g_onUpdateFunction,
1742                 onEnterInterval = null;
1743
1744         elmButton.onclick = clickOK;
1745         
1746         var BASE_PATH = pettanr.LOCAL === true ? 'resource_pictures\/' : pettanr.CONST.PETTANR_ROOT_PATH + 'resource_pictures\/',
1747                 THUMB_PATH = BASE_PATH, // + 'thumbnail/',
1748                 LIMIT_FILESIZE = 1024 * 10; // 10KB
1749
1750         var ImageGroupIconClass = function( INDEX, file ){
1751                 var elmIconWrap = elmIconOrigin.cloneNode( true ),
1752                         elmIconTitle = pettanr.util.getElementsByClassName( elmIconWrap, 'image-gruop-item-title' )[ 0 ],
1753                         data = pettanr.driver._getAPI().getFileData( file ),
1754                         SRC = [ BASE_PATH, data.id, '.', data.ext ].join( ''),
1755                         LOW_SRC = data.filesize && data.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext ].join( '') : null,
1756                         reversibleImage = null,
1757                         onEnterFlag = false,
1758                         imgW, imgH;
1759                 elmContainer.appendChild( elmIconWrap );
1760                 elmIconWrap.style.left = ( INDEX * itemW ) + 'px';
1761                 elmIconTitle.appendChild( document.createTextNode( data.filesize + 'bytes' ));
1762
1763                 function onImageLoad( url, _imgW, _imgH ){
1764                         if( reversibleImage === null) {
1765                                 alert( url);
1766                                 return;
1767                         }
1768                         data.width = imgW = _imgW || data.width || 64;
1769                         data.height = imgH = _imgH || data.height || 64;
1770                         elmIconTitle.firstChild.data = imgW + 'x' + imgH;
1771                         var zoom = 128 /( imgW > imgH ? imgW : imgH),
1772                                 MATH_FLOOR = Math.floor
1773                                 h = MATH_FLOOR( imgH *zoom ),
1774                                 w = MATH_FLOOR( imgW *zoom );
1775                         reversibleImage.elm.style.cssText = [
1776                                 'width:', w, 'px;',
1777                                 'height:', h +'px;',
1778                                 'margin:', MATH_FLOOR( itemH /2 -h /2 ), 'px ', MATH_FLOOR( itemW /2 -w /2 ), 'px 0'
1779                         ].join('');
1780                         reversibleImage.resize( w, h );
1781                         elmIconWrap.onclick = onClick;
1782                 }
1783                 
1784                 function onClick( e ){
1785                         if( _g_onUpdateFunction ) {
1786                                 //if( LOW_SRC === null){
1787                                         window[ _g_onUpdateFunction]( data );
1788                                         window[ _g_onUpdateFunction] = null;
1789                                 /*
1790                                 } else {
1791                                         var _onLoad = pettanr.util.createGlobalFunc( [
1792                                                         'function( url, w, h ){',
1793                                                                 'window["', _g_onUpdateFunction, '"]( url, w || ', data.width,',  h || ', data.height,');',
1794                                                                 'window["', _g_onUpdateFunction, '"] = null;',
1795                                                         '}'
1796                                                 ].join( '')),
1797                                                 _onError = pettanr.util.createGlobalFunc( [
1798                                                         'function( url){',
1799                                                                 'window["', _g_onUpdateFunction, '"]( url, ', data.width || 64 ,', ', data.height || 64,');',
1800                                                                 'window["', _g_onUpdateFunction, '"] = null;',
1801                                                         '}'
1802                                                 ].join( ''));
1803                                         pettanr.util.loadImage( SRC, window[ _onLoad], window[ _onError]);
1804                                         window[ _onLoad] = window[ _onError] = undefined;
1805                                 }*/
1806                         }
1807                         pettanr.premiumSatge.shutdown();
1808                 }
1809                 
1810                 this.onEnter = function(){
1811                         if( onEnterFlag === true ) return;
1812                         reversibleImage = pettanr.image.createReversibleImage( LOW_SRC || SRC, itemW, itemH, onImageLoad );
1813                         elmIconWrap.appendChild( reversibleImage.elm );
1814                         onEnterFlag = true;
1815                 }
1816                 this.destroy = function(){
1817                         reversibleImage && reversibleImage.destroy();
1818                         pettanr.util.removeAllChildren( elmIconWrap );
1819                         elmContainer.removeChild( elmIconWrap );
1820                         file.destroy();
1821                         reversibleImage = elmIconWrap = elmIconTitle = data = file = null;
1822                         delete this.destroy;
1823                 }
1824         }
1825         
1826         function onEnterShowImage(){
1827                 var l = ICON_ARRAY.length,
1828                         _start = -wrapX /itemW -1,
1829                         _end = _start + winW /itemW +1;
1830                 for( var i=0; i<l; ++i){
1831                         _start < i && i < _end && ICON_ARRAY[ i].onEnter();
1832                 }
1833                 onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1834                 onEnterInterval = null;
1835         }
1836         function clickOK(){
1837                 pettanr.premiumSatge.shutdown();
1838         }
1839         function onMouseWheel( e, delta ){
1840                 if( winW < containerW){
1841                         wrapX += delta * WHEEL_DELTA;
1842                         wrapX = wrapX > 0 ? 0 : wrapX < winW -containerW ? winW -containerW : wrapX;
1843                         jqContainer.css( { left: wrapX});
1844                         
1845                         onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1846                         onEnterInterval = window.setTimeout( onEnterShowImage, 500);
1847                 }
1848                 //e.stopPropagation();
1849                 return false;                   
1850         }
1851         
1852         /* grobal method */
1853         // this.rootElement = elmWrap;
1854         this.displayName = 'premiumStage';
1855         this.ID          = 'premiumStage';
1856         this.rootElement = elmWrap;
1857         this.MIN_WIDTH   = 320;
1858         this.MIN_HEIGHT  = 320;
1859         this.init = function(){
1860                 jqContainer = $( elmContainer ).mousewheel( onMouseWheel );
1861                 delete instance.init;
1862         }
1863         this.onOpen = function( _windowW, _windowH, _ARTISTIDorFILE, _onUpdateFunction ){
1864                 instance.init && instance.init();
1865                 
1866                 var _data, _artistID = -1;
1867                 
1868                 if( pettanr.driver.isPettanrFileInstance( _ARTISTIDorFILE ) === true ){
1869                         _data = pettanr.driver._getAPI().getFileData( _ARTISTIDorFILE );
1870                         if( _ARTISTIDorFILE.getType() === pettanr.driver.FILE_TYPE.ARTIST || pettanr.driver._getMyPicturesData() === _data ){
1871                                 _artistID = _data.id || -1;
1872                         }
1873                 } else
1874                 if( Type.isNumber( _ARTISTIDorFILE ) === true ){
1875                         _artistID = _ARTISTIDorFILE;
1876                 }
1877                 
1878                 //onUpdateFunction = _onUpdateFunction;
1879                 if( _onUpdateFunction ){
1880                         _g_onUpdateFunction = pettanr.util.createGlobalFunction( _onUpdateFunction);
1881                 } else {
1882                         _g_onUpdateFunction = null;
1883                 }
1884                 
1885                 var _index = ARTIST_ROOT_FILE.search( {
1886                                 id:   _artistID,
1887                                 type: pettanr.driver.FILE_TYPE.ARTIST
1888                         } )[ 0 ],
1889                         _artistFile = ARTIST_ROOT_FILE.getChildFileByIndex( _index ),
1890                         i, l = 0;
1891                 if( _artistFile !== null ){
1892                         for( i=0, l=_artistFile.getChildFileLength(); i<l; ++i ){
1893                                 ICON_ARRAY.push( new ImageGroupIconClass( i, _artistFile.getChildFileByIndex( i ) ));
1894                         }
1895                         elmName.firstChild.data = _artistFile.getName() + l;
1896                         _artistFile.destroy();
1897                 }
1898                 
1899                 wrapX = 0;
1900                 containerW = l * itemW;
1901                 
1902                 winW = _windowW;
1903                 winH = _windowH;
1904                 var w = winW > containerW ? winW : containerW,
1905                         h = _windowH > containerH ? containerH : _windowH,
1906                         MATH_FLOOR = Math.floor;
1907                 
1908                 onEnterShowImage();
1909                 
1910                 jqContainer.css( {
1911                         width:          w,
1912                         height:         0,
1913                         left:           0,
1914                         top:            MATH_FLOOR( _windowH /2)
1915                 }).stop().animate( {
1916                         height:         h,
1917                         top:            MATH_FLOOR( _windowH /2 -h /2)
1918                 });
1919                 
1920                 elmButton.style.cssText = [
1921                         'left:', MATH_FLOOR( winW /2 - buttonW /2), 'px;',
1922                         'top:', MATH_FLOOR( _windowH /2 + containerH /2 +10), 'px'
1923                 ].join('');
1924         }
1925         this.onPaneResize = function( _windowW, _windowH ){
1926                 var w = _windowW > containerW ? _windowW : containerW,
1927                         h = _windowH > containerH ? containerH : _windowH,
1928                         MATH_FLOOR = Math.floor,
1929                         offsetW = MATH_FLOOR( _windowW /2 -winW /2);
1930                         
1931                 winW = _windowW;
1932                 winH = _windowH;
1933                 if( offsetW <= 0){ // smaller
1934                         jqContainer.css( {
1935                                 left:                           offsetW,
1936                                 width:                          w
1937                         }).animate( {
1938                                 left:                           0,
1939                                 top:                            MATH_FLOOR( _windowH /2 -h /2)
1940                         });                                     
1941                 } else {
1942                         jqContainer.css( { // bigger
1943                                 left:                           0,
1944                                 width:                          w,
1945                                 borderLeftWidth:        offsetW
1946                         }).animate( {
1947                                 top:                            MATH_FLOOR( _windowH /2 -h /2),
1948                                 borderLeftWidth:        0
1949                         });
1950                 }
1951                 elmButton.style.cssText = [
1952                         'left:', MATH_FLOOR( _windowW /2 -buttonW /2), 'px;',
1953                         'top:', MATH_FLOOR( _windowH /2 +containerH /2 +10), 'px'
1954                 ].join('');
1955                 onEnterShowImage();
1956         }
1957         this.onClose = function(){
1958                 jqContainer.stop().animate( {
1959                                 height: 0,
1960                                 top:    Math.floor( winH /2 )
1961                         });
1962                 while( ICON_ARRAY.length > 0 ){
1963                         ICON_ARRAY.shift().destroy();
1964                 }
1965                 onEnterInterval !== null && window.clearTimeout( onEnterInterval );
1966                 onEnterInterval = _g_onUpdateFunction = null;
1967         }
1968 });
1969
1970
1971 /* ----------------------------------------
1972  * Text Editor
1973  *  - overlay
1974  */
1975 pettanr.textEditor = pettanr.view.registerApplication( function(){
1976         var jqWrap, jqTextarea, jqButton,
1977                 textElement, onUpdateFunction,
1978                 ID = 'textEditor',
1979                 panelX, panelY,
1980                 instance = this;
1981         //pettanr.key.addKeyDownEvent( ID, 69, false, false, clickOK);
1982         
1983         function clickOK(){
1984                 textElement && textElement.text( jqTextarea.val() );
1985                 onUpdateFunction && onUpdateFunction( textElement );
1986                 pettanr.textEditor.shutdown();
1987         }
1988         
1989         function keyCancel( e ){
1990                 if( e.keyCode === 69 && e.shiftKey === false && e.ctrlKey === true){
1991                         clickOK();
1992                         e.preventDefault();
1993                 e.keyCode = 0;
1994                 e.cancelBubble = true;
1995                 e.returnValue = false;
1996                         return false;
1997                 }       
1998         }
1999         
2000         /* grobal method */
2001         // this.rootElement = elmWrap;
2002         this.displayName = 'textEditor';
2003         this.ID          = 'textEditor';
2004         this.rootElement = document.getElementById( 'speach-editor-wrapper' );
2005         this.MIN_WIDTH   = 320;
2006         this.MIN_HEIGHT  = 320;
2007         this.init = function(){
2008                 instance.jqWrap = jqWrap = $( '#speach-editor-wrapper' ).hide();
2009                 jqTextarea = $( '#speach-editor' ).keydown( keyCancel );
2010                 jqButton = $( '#speach-edit-complete-button').click( clickOK );
2011                 delete instance.init;
2012         }
2013         this.jqWrap = null;
2014         this.onOpen = function( _w, _h, _panelX, _panelY, _textElement, _onUpdateFunction ){
2015                 instance.init && instance.init();
2016                 
2017                 panelX = _panelX;
2018                 panelY = _panelY;
2019                 textElement = _textElement;
2020                 onUpdateFunction = _onUpdateFunction || null;
2021                 
2022                 var h = _textElement.h;
2023                 
2024                 instance.onPaneResize( _w, _h );
2025                 jqTextarea.val( _textElement.text() ).focus();
2026                 
2027                 /*
2028                  * ie6,7は、textarea { width:100%}でも高さが変わらない。rowsを設定。
2029                  */
2030                 pettanr.ua.isIE === true && pettanr.ua.ieVersion <= 7 && setTimeout( function(){
2031                         var rows = 0;
2032                         while( jqTextarea.height() < h){
2033                                 rows++;
2034                                 jqTextarea.attr( 'rows', rows);
2035                         }
2036                         rows > 1 && jqTextarea.attr( 'rows', rows -1 );
2037                 }, 0);
2038         }
2039         this.onPaneResize = function( _w, _h ){
2040                 jqWrap.show().css( {
2041                         left:                   textElement.x + panelX,
2042                         top:                    textElement.y + panelY,
2043                         width:                  textElement.w,
2044                         height:                 textElement.h
2045                 });
2046         }
2047         this.onClose = function(){
2048                 jqWrap.hide();
2049                 textElement = onUpdateFunction = null;          
2050         }
2051 });
2052
2053 // i18n
2054 // login
2055 // lib
2056
2057 pettanr.fn( pettanr.view);
2058 pettanr.fn( pettanr.overlay);
2059 pettanr.fn( pettanr.key);
2060 pettanr.fn( pettanr.balloon);
2061
2062 pettanr.fn( pettanr.editor);
2063
2064 pettanr.fn( pettanr.file);
2065 pettanr.fn( pettanr.finder);
2066 pettanr.fn( pettanr.gallery);
2067 pettanr.fn( pettanr.cabinet);
2068
2069 $(window).ready( pettanr.init);