OSDN Git Service

pettanR 0.4.x
[pettanr/clientJs.git] / 0.4.x / work.js
1 /*\r
2  * pettanR work.js\r
3  *   version 0.4.0\r
4  *   \r
5  * author:\r
6  *   itozyun\r
7  * licence:\r
8  *   3-clause BSD\r
9  *\r
10  * \r
11  * ----------------------------------------\r
12  * naming rules\r
13  * \r
14  *  Class\r
15  *    ThisIsClass\r
16  *  \r
17  *  const\r
18  *    THIS_IS_CONST = 'this is const';\r
19  *  \r
20  *  var\r
21  *    thisIsVar\r
22  *   \r
23  *  value of jquery\r
24  *    jqWrapper, JQ_WRAPPER\r
25  *  \r
26  *  value of dom element\r
27  *    elmWrapper, ELM_WRAP\r
28  * \r
29  *      value of vml element\r
30  *    vmlImg, VML_SHAPE\r
31  * \r
32  */\r
33 \r
34                 pettanr.LINE_FEED_CODE_TEXTAREA = ( function(){\r
35                         var text = document.getElementById( 'shadowTxtarea'),\r
36                                 form = text.parentNode;\r
37                         form.parentNode.removeChild( form);\r
38                         return text.value;\r
39                 })();\r
40                 pettanr.LINE_FEED_CODE_PRE = ( function(){\r
41                         var pre = document.getElementById( 'shadowPre');\r
42                         pre.parentNode.removeChild( pre);\r
43                         return pettanr.ua.isIE === true ? this.LINE_FEED_CODE_TEXTAREA : pre.innerHTML; // ie ??                                \r
44                 })();\r
45 \r
46 \r
47 \r
48 /* ----------------------------------------\r
49  *   pettanr.editor\r
50  *    - MENU_BAR_CONTROL\r
51  *    - HISTORY\r
52  *    - SAVE_CONTROL\r
53  *    - TEXT_EDITOR_CONTROL\r
54  *    - IMAGE_GROUP_EXPROLER\r
55  *    - WINDOW_CONTROL\r
56  *       - WindowClass\r
57  *    - INFOMATION_WINDOW\r
58  *    - TOOL_BOX_WINDOW\r
59  *    - HELP_DOCUMENTS_WINDOW\r
60  *    - CANVAS_CONTROL\r
61  *       - GRID_CONTROL\r
62  *       - WHITE_GLASS_CONTROL\r
63  *       - PANEL_CONTROL\r
64  *       - COMIC_ELEMENT_CONTROL\r
65  *          - PanelResizerClass\r
66  *          - COMIC_ELEMENT_OPERATOR\r
67  *             - TAIL_CONTROLER\r
68  *          - ImageElementClass\r
69  *          - TextElementClass\r
70  * \r
71  */\r
72 pettanr.editor = ( function(){\r
73         var COMIC_ELEMENT_TYPE_IMAGE = 0,\r
74                 COMIC_ELEMENT_TYPE_TEXT = 1,\r
75                 MOUSE_LISTENER_ARRAY = [],\r
76                 ELM_MOUSE_EVENT_CHATCHER = document.getElementById( 'mouse-operation-catcher'),\r
77                 jqMouseEventChacher,\r
78                 jqEditor,\r
79                 windowW, windowH,\r
80                 currentListener = null,\r
81                 currentCursor = '',\r
82                 option;\r
83 \r
84 /* ----------------------------------------\r
85  * MENU BAR\r
86  * div\r
87  *   div.title\r
88  *   ul\r
89  *     li\r
90  *        a\r
91  *          span\r
92  *          kbd shortcut\r
93  */\r
94         var MENU_BAR_CONTROL = ( function(){\r
95                 var BAR_ID = 'menu-bar',\r
96                         ELM_BAR = document.getElementById( BAR_ID),\r
97                         ELM_ITEM_CLASSNAME = 'menu-bar-item',\r
98                         ELM_ITEM_ORIGN = ( function(){\r
99                                 var ret = document.createElement( 'DIV'),\r
100                                         div = document.createElement( 'DIV'),\r
101                                         ul = document.createElement( 'UL');\r
102                                 ret.className = ELM_ITEM_CLASSNAME;\r
103                                 ret.appendChild( div);\r
104                                 ret.appendChild( ul);\r
105                                 return ret;\r
106                         })(),\r
107                         ELM_SELECTION_ORIGN = ( function(){\r
108                                 var ret = document.createElement( 'LI'),\r
109                                         a = document.createElement( 'A'),\r
110                                         span = document.createElement( 'SPAN'),\r
111                                         key = document.createElement( 'KBD');\r
112                                 a.appendChild( span);\r
113                                 a.appendChild( key);\r
114                                 ret.appendChild( a);\r
115                                 a.href = '#';\r
116                                 return ret;\r
117                         })(),\r
118                         EMPTY_FUNCTION = new Function,\r
119                         ITEM_ARRAY = [],\r
120                         barH = pettanr.util.getElementSize( ELM_BAR).height,\r
121                         itemW = pettanr.util.getElementSize( ELM_ITEM_ORIGN).width,\r
122                         selectionW = pettanr.util.getElementSize( ELM_ITEM_ORIGN.getElementsByTagName( 'UL')[ 0]).width,\r
123                         jqStage, jqBar;\r
124                 ELM_BAR.style.top = ( -barH) +'px';\r
125 \r
126                 var MenubarSelectionClass = function( container, title, shortcut, visible, separateAfter){\r
127                         var ELM_WRAPPER = ELM_SELECTION_ORIGN.cloneNode( true),\r
128                                 ELM_TITLE = ELM_WRAPPER.getElementsByTagName( 'SPAN')[ 0];\r
129                         updateTitle( title);\r
130                         updateVisible( visible);\r
131                         \r
132                         ( function(){\r
133                                 var ELM_SHORTCUT = ELM_WRAPPER.getElementsByTagName( 'KBD')[ 0];\r
134                                 if( shortcut){\r
135                                         ELM_SHORTCUT.innerHTML = shortcut;\r
136                                 } else {\r
137                                         ELM_SHORTCUT.parentNode.removeChild( ELM_SHORTCUT);\r
138                                 }                               \r
139                         })();\r
140 \r
141                         container.appendChild( ELM_WRAPPER);\r
142                         \r
143                         function updateTitle( _title){\r
144                                 ELM_TITLE.innerHTML = title = _title;\r
145                         }\r
146                         function updateVisible( _visible){\r
147                                 _visible !== undefined && ( function(){\r
148                                         visible = !!_visible;\r
149                                         ELM_WRAPPER.className = visible === true ? '' : 'disabled';\r
150                                 })();\r
151                         }\r
152                         return {\r
153                                 elm: ELM_WRAPPER,\r
154                                 title: function( _title){\r
155                                         _title !== undefined && updateTitle( _title);\r
156                                         return title;\r
157                                 },\r
158                                 visible: function( _visible){\r
159                                         visible !== !!_visible && updateVisible( _visible);\r
160                                         return visible;\r
161                                 },\r
162                                 separateAfter: separateAfter\r
163                         }\r
164                 }\r
165 \r
166                 var MenuBarItemClass = function( title, opt_callbackArray){\r
167                         var ELM_WRAPPER = ELM_ITEM_ORIGN.cloneNode( true),\r
168                                 ELM_TITLE = ELM_WRAPPER.getElementsByTagName( 'DIV')[ 0],\r
169                                 ELM_SELECTION = ELM_WRAPPER.getElementsByTagName( 'UL')[ 0],\r
170                                 INDEX = ITEM_ARRAY.length,\r
171                                 SELECTION_CALLBACK_ARRAY = opt_callbackArray || [],\r
172                                 numSelection = 0,\r
173                                 visible = false;\r
174                         ELM_TITLE.innerHTML = title;\r
175                         \r
176                         ELM_WRAPPER.style.left = ( itemW * INDEX) +'px';\r
177                         ELM_BAR.appendChild( ELM_WRAPPER);\r
178                         \r
179                         function onClick( e){\r
180                                 var that = this,\r
181                                         i = ( function(){\r
182                                                 var parent = that.parentNode,\r
183                                                         children = parent.getElementsByTagName( 'LI'),\r
184                                                         l = children.length;\r
185                                                 for(var i=0; i<l; ++i){\r
186                                                         if( children[ i] === that) return i;\r
187                                                 }\r
188                                                 return -1;\r
189                                         })();\r
190                                 i !== -1 && this.className !== 'disabled' && SELECTION_CALLBACK_ARRAY[ i]();\r
191                                 e.stopPropagation();\r
192                                 return false;                           \r
193                         }\r
194                         return {\r
195                                 elm: ELM_WRAPPER,\r
196                                 onClick: onClick,\r
197                                 init: function(){\r
198                                         $( ELM_SELECTION).children( 'li').click( onClick);\r
199                                         delete this.init;\r
200                                 },\r
201                                 show: function(){\r
202                                         if( visible === true) return;\r
203                                         jqStage.append( ELM_WRAPPER);\r
204                                         ELM_WRAPPER.className = ELM_ITEM_CLASSNAME +'-focus';\r
205                                         this.onShow && setTimeout( this.onShow, 0);\r
206                                         visible = true;\r
207                                 },\r
208                                 hide: function(){\r
209                                         if( visible === false) return;\r
210                                         ELM_BAR.appendChild( ELM_WRAPPER);\r
211                                         ELM_WRAPPER.className = ELM_ITEM_CLASSNAME;\r
212                                         this.onHide && setTimeout( this.onHide, 0);\r
213                                         visible = false;\r
214                                 },\r
215                                 createSelection: function( title, shortcut, callback, visible, separateBefore, separateAfter){\r
216                                         var ret = MenubarSelectionClass.apply( {}, [ ELM_SELECTION, title, shortcut, visible, separateAfter]),\r
217                                                 before = SELECTION_CALLBACK_ARRAY.length > 0 ? SELECTION_CALLBACK_ARRAY[ SELECTION_CALLBACK_ARRAY.length -1] : null;\r
218                                         SELECTION_CALLBACK_ARRAY.push( callback);\r
219                                         if( ( separateBefore === true && before) || ( before && before.separateAfter === true)){\r
220                                                 ret.elm.style.borderTop = '1px solid #ccc';\r
221                                         }\r
222                                         return ret;\r
223                                 }\r
224                         }\r
225                 }\r
226 \r
227                 \r
228                 function createMenubarItem( title){\r
229                         var _item = MenuBarItemClass.apply( {}, [ title]);\r
230                         ITEM_ARRAY.push( _item);\r
231                         return _item;\r
232                 }\r
233                 return {\r
234                         init: function(){\r
235                                 jqStage = jqEditor;\r
236                                 jqBar = $( '#' +BAR_ID).animate( { top: 0});\r
237 \r
238                                 var l = ITEM_ARRAY.length;\r
239                                 for( var i=0; i<l; ++i){\r
240                                         ITEM_ARRAY[ i].init();\r
241                                 }\r
242 \r
243                                 delete MENU_BAR_CONTROL.init;\r
244                         },\r
245                         h: barH,\r
246                         onMouseMove: function( _mouseX, _mouseY){\r
247                                 if( barH >= _mouseY){\r
248                                         return true;\r
249                                 }\r
250                                 var l = ITEM_ARRAY.length;\r
251                                 for( var i=0; i<l; ++i){\r
252                                         ITEM_ARRAY[ i].hide();\r
253                                 }\r
254                                 return false;\r
255                         },\r
256                         onMouseUp: function( _mouseX, _mouseY){\r
257                                 return false;\r
258                         },\r
259                         onMouseDown: function( _mouseX, _mouseY){\r
260                                 var l = ITEM_ARRAY.length;\r
261                                 if( barH < _mouseY || itemW * l < _mouseX) return false;\r
262                                 for( var i=0; i<l; ++i){\r
263                                         if( i * itemW <= _mouseX && _mouseX < ( i +1) * itemW){\r
264                                                 ITEM_ARRAY[ i].show();\r
265                                         } else {\r
266                                                 ITEM_ARRAY[ i].hide();\r
267                                         }\r
268                                 }\r
269                                 return true;\r
270                         },\r
271                         busy: function( _busy){\r
272                                 return false;\r
273                         },\r
274                         onWindowResize: function( _windowW, _windowH){\r
275                                 \r
276                         },\r
277                         QUIT: createMenubarItem( 'Quit'),\r
278                         EDIT: createMenubarItem( 'Edit'),\r
279                         WINDOW: createMenubarItem( 'Window'),\r
280                         HELP: pettanr.util.extend( createMenubarItem( 'Help'), {\r
281                                         createAjaxSelection: function( callback){\r
282                                                 var elmLoading = document.createElement( 'li'),\r
283                                                         that = this,\r
284                                                         elmSelection = this.elm.getElementsByTagName( 'UL')[ 0];\r
285                                                 elmSelection.appendChild( elmLoading);\r
286                                                 elmLoading.className = 'loading';\r
287                                                 elmLoading.style.height = '90px';                                                       \r
288 \r
289                                                 this.onShow = callback;\r
290                                                 callback = null;\r
291                                                 \r
292                                                 delete this.createAjaxSelection;\r
293                                                 return function(){\r
294                                                         elmSelection.removeChild( elmLoading);\r
295                                                         $( elmSelection).children( 'li').click( that.onClick);\r
296                                                         elmLoading = elmSelection = null;\r
297                                                         delete that.onShow;\r
298                                                         that = null;\r
299                                                 }\r
300                                         }\r
301                                 })\r
302                 }\r
303         })();\r
304 \r
305 \r
306 /* ----------------------------------------\r
307  * HISTORY\r
308  */\r
309         var HISTORY = ( function() {\r
310                 var     STACK_BACK = [],\r
311                         STACK_FORWARD = [],\r
312                         MENUBAR_BACK = MENU_BAR_CONTROL.EDIT.createSelection( 'back', 'ctrl + z', back, false),\r
313                         MENUBAR_FORWARD = MENU_BAR_CONTROL.EDIT.createSelection( 'forward', 'ctrl + y', forward, false, false, true),\r
314                         log;\r
315                         \r
316                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 90, false, true, back);       // ctrl + Z\r
317                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 90, true, true, forward);     // ctrl + shift + Z\r
318                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 89, false, true, forward); // ctrl + Y\r
319 \r
320                 function back(){\r
321                         /*\r
322                          * currentを控えてSTACK_FORWARD.push(current)\r
323                          * STACK_BACK.pop()を実行してcurrentに\r
324                          */\r
325                         if( STACK_BACK.length === 0) return;\r
326 \r
327                         var state = STACK_BACK.pop();\r
328                         state && state.fn( state.argBack);\r
329                         MENUBAR_BACK.visible( STACK_BACK.length !== 0);\r
330                         SAVE_CONTROL.panelUpdated( STACK_BACK.length !== 0);\r
331                         \r
332                         STACK_FORWARD.push( state);\r
333                         MENUBAR_FORWARD.visible( true);\r
334                 }\r
335                 function forward(){\r
336                         if( STACK_FORWARD.length === 0) return;\r
337                         \r
338                         var state = STACK_FORWARD.pop();\r
339                         state.fn( state.argForword);\r
340                         MENUBAR_FORWARD.visible( STACK_FORWARD.length !== 0);\r
341                         \r
342                         STACK_BACK.push( state);\r
343                         MENUBAR_BACK.visible( true);\r
344                         SAVE_CONTROL.panelUpdated( true);\r
345                 }\r
346                 return {\r
347                         init: function(){\r
348                                 log = $( '#history-log');\r
349                                 delete HISTORY.init;\r
350                         },\r
351                     saveState: function( _function, _argBack, _argForword, _destory) {\r
352                         STACK_BACK.push( {\r
353                                 fn:                     _function,\r
354                                 argBack:        _argBack,\r
355                                         argForword:     _argForword,\r
356                                         destroy:        _destroy\r
357                         });\r
358                         MENUBAR_BACK.visible( true);\r
359                                 SAVE_CONTROL.panelUpdated( true);\r
360 \r
361                         while( STACK_FORWARD.length > 0){\r
362                                         var _stack = STACK_FORWARD.shift(),\r
363                                                 _destroy = _stack.destroy,\r
364                                                 _value;\r
365                                         _argBack = _stack.argBack;\r
366                                         _argForword = _stack.argForword;\r
367                                         _stack.fn = null;\r
368                                         if( typeof _argBack === 'array'){\r
369                                                 while( _argBack.length > 0){\r
370                                                         _value = _argBack.shift();\r
371                                                         _destroy === true && typeof _value.destroy === 'function' && _value.destroy();\r
372                                                 }\r
373                                         }\r
374                                         if( typeof _argForword === 'array'){\r
375                                                 while( _argForword.length > 0){\r
376                                                         _value = _argForword.shift();\r
377                                                         _destroy === true && typeof _value.destroy === 'function' && _value.destroy();\r
378                                                 }                                               \r
379                                         }\r
380                                 }\r
381                                 MENUBAR_FORWARD.visible( false);\r
382                     }           \r
383                 }\r
384         })();\r
385 \r
386 \r
387 /* ----------------------------------------\r
388  *     Save Control\r
389  */\r
390 \r
391         var SAVE_CONTROL = ( function(){\r
392                 var SAVE = MENU_BAR_CONTROL.QUIT.createSelection( 'save', 'ctrl + S', quit, false),\r
393                         SAVE_AND_QUIT = MENU_BAR_CONTROL.QUIT.createSelection( 'save & quit', null, quit, false, false, true),\r
394                         SAVE_AS_HTML = MENU_BAR_CONTROL.QUIT.createSelection( 'get as html', null, outputAsHtml, true, false, true),\r
395                         SAVE_AS_JSON_STRING = MENU_BAR_CONTROL.QUIT.createSelection( 'get JsonStr', null, outputAsJsonString, true, false, true),\r
396                         QUIT = MENU_BAR_CONTROL.QUIT.createSelection( 'quit', null, quit, true, true),\r
397                         updated = false;\r
398                 \r
399                 function quit(){\r
400                 }\r
401                 \r
402                 function outputAsHtml(){\r
403                         alert( COMIC_ELEMENT_CONTROL.getAsHTML( true, false));\r
404                 }\r
405                 function outputAsJsonString(){\r
406                         alert( COMIC_ELEMENT_CONTROL.getAsJsonString());\r
407                 }\r
408                 return {\r
409                         quit: quit,\r
410                         panelUpdated: function( _updated){\r
411                                 if( _updated !== undefined && updated !== _updated){\r
412                                         SAVE.visible( !!_updated);\r
413                                         SAVE_AND_QUIT.visible( !!_updated);\r
414                                         updated = !!_updated;\r
415                                 }\r
416                                 return updated;\r
417                         },\r
418                         save: function(){\r
419                                 \r
420                         }\r
421                 }\r
422         })();\r
423 \r
424 /* ----------------------------------------\r
425  *     Text Editor (Overlay)\r
426  */\r
427         \r
428         var TEXT_EDITOR_CONTROL = ( function(){\r
429                 var jqWrap, jqTextarea, jqButton,\r
430                         textElement, onUpdateFunction;\r
431                 \r
432                 pettanr.key.addKeyDownEvent( this.ID, 69, false, false, clickOK);\r
433                 \r
434                 function close(){\r
435                         jqWrap.hide();\r
436                         textElement = onUpdateFunction = null;          \r
437                 }\r
438                 function clickOK(){\r
439                         pettanr.overlay.hide();\r
440                         textElement && textElement.text( jqTextarea.val());\r
441                         onUpdateFunction && onUpdateFunction( textElement);\r
442                         close();                        \r
443                 }\r
444                 return {\r
445                         init: function(){\r
446                                 this.jqWrap = jqWrap = $( '#speach-editor-wrapper').hide();\r
447                                 jqTextarea = $( '#speach-editor').keydown( function( e){\r
448                                         if( e.keyCode === 69 && e.shiftKey === false && e.ctrlKey === true){\r
449                                                 clickOK();\r
450                                                 e.preventDefault();\r
451                                         e.keyCode = 0;\r
452                                         e.cancelBubble = true;\r
453                                         e.returnValue = false;\r
454                                                 return false;\r
455                                         }\r
456                                 });\r
457                                 jqButton = $( '#speach-edit-complete-button').click( clickOK);\r
458                                 delete TEXT_EDITOR_CONTROL.init;\r
459                         },\r
460                         jqWrap: null,\r
461                         show: function( _textElement, _onUpdateFunction){\r
462                                 textElement = _textElement;\r
463                                 onUpdateFunction = _onUpdateFunction || null;\r
464                                 pettanr.overlay.show( this);\r
465                                 var h = _textElement.h;\r
466                                 jqWrap.show().css( {\r
467                                         left:                   _textElement.x +PANEL_CONTROL.x(),\r
468                                         top:                    _textElement.y +PANEL_CONTROL.y(),\r
469                                         width:                  _textElement.w,\r
470                                         height:                 h\r
471                                 });\r
472                                 jqTextarea.val( _textElement.text()).focus();\r
473                                 \r
474                                 /*\r
475                                  * ie6,7は、textarea { width:100%}でも高さが変わらない。rowsを設定。\r
476                                  */\r
477                                 pettanr.ua.isIE === true && pettanr.ua.ieVersion <= 7 && setTimeout( function(){\r
478                                         var rows = 0;\r
479                                         while( jqTextarea.height() < h){\r
480                                                 rows++;\r
481                                                 jqTextarea.attr( 'rows', rows);\r
482                                         }\r
483                                         rows > 1 && jqTextarea.attr( 'rows', rows -1);\r
484                                 }, 0);\r
485                         },\r
486                         onWindowResize: function(){\r
487                                 textElement && this.show( textElement);\r
488                         },\r
489                         onClose: close,\r
490                         ID: 'textEditor'\r
491                 }\r
492         })();\r
493 \r
494 /* ----------------------------------------\r
495  *     Image Group Exproler (Overlay)\r
496  */\r
497         var IMAGE_GROUP_EXPROLER = ( function(){\r
498                 var ICON_ARRAY = [],\r
499                         WHEEL_DELTA = 64,\r
500                         containerW, containerH, wrapX,\r
501                         jqWrap, jqContainer, jqItemOrigin,\r
502                         itemW, itemH,\r
503                         jqName, jqButton, buttonW,\r
504                         onUpdateFunction,\r
505                         winW,\r
506                         onEnterInterval = null;\r
507                 \r
508                 var BASE_PATH = pettanr.LOCAL === false ? 'http://pettan.heroku.com/images/' : 'images/',\r
509                         THUMB_PATH = BASE_PATH, // + 'thumbnail/',\r
510                         LIMIT_FILESIZE = 1024 * 10; // 10KB\r
511                 var IMAGE_DATA = {\r
512                                 pen001: [\r
513                                     {\r
514                                         "created_at": "2011-11-13T08:57:39Z", \r
515                                         "ext": "png", \r
516                                         "filesize": 9969, \r
517                                         "height": 463, \r
518                                         "id": 1, \r
519                                         "updated_at": "2011-11-13T08:57:39Z", \r
520                                         "width": 441\r
521                                     }, \r
522                                     {\r
523                                         "created_at": "2011-11-13T08:57:54Z", \r
524                                         "ext": "gif", \r
525                                         "filesize": 5418, \r
526                                         "height": 500, \r
527                                         "id": 2, \r
528                                         "updated_at": "2011-11-13T08:57:54Z", \r
529                                         "width": 500\r
530                                     }, \r
531                                     {\r
532                                         "created_at": "2011-11-13T08:58:06Z", \r
533                                         "ext": "gif", \r
534                                         "filesize": 8758, \r
535                                         "height": 464, \r
536                                         "id": 3, \r
537                                         "updated_at": "2011-11-13T08:58:06Z", \r
538                                         "width": 366\r
539                                     }, \r
540                                     {\r
541                                         "created_at": "2011-11-13T08:58:23Z", \r
542                                         "ext": "gif", \r
543                                         "filesize": 9383, \r
544                                         "height": 480, \r
545                                         "id": 4, \r
546                                         "updated_at": "2011-11-13T08:58:23Z", \r
547                                         "width": 392\r
548                                     }, \r
549                                     {\r
550                                         "created_at": "2011-11-13T08:58:33Z", \r
551                                         "ext": "gif", \r
552                                         "filesize": 11061, \r
553                                         "height": 500, \r
554                                         "id": 5, \r
555                                         "updated_at": "2011-11-13T08:58:33Z", \r
556                                         "width": 500\r
557                                     }, \r
558                                     {\r
559                                         "created_at": "2011-11-20T09:50:43Z", \r
560                                         "ext": "gif", \r
561                                         "filesize": 1131, \r
562                                         "height": 126, \r
563                                         "id": 6, \r
564                                         "updated_at": "2011-11-20T09:50:43Z", \r
565                                         "width": 259\r
566                                     }, \r
567                                     {\r
568                                         "created_at": "2011-11-20T09:50:55Z", \r
569                                         "ext": "gif", \r
570                                         "filesize": 1125, \r
571                                         "height": 126, \r
572                                         "id": 7, \r
573                                         "updated_at": "2011-11-20T09:50:55Z", \r
574                                         "width": 259\r
575                                     }, \r
576                                     {\r
577                                         "created_at": "2011-11-20T11:33:12Z", \r
578                                         "ext": "gif", \r
579                                         "filesize": 17919, \r
580                                         "height": 600, \r
581                                         "id": 8, \r
582                                         "updated_at": "2011-11-20T11:33:12Z", \r
583                                         "width": 800\r
584                                     },\r
585                                     {\r
586                                         "created_at": "2011-11-20T11:33:12Z", \r
587                                         "ext": "gif", \r
588                                         "filesize": 17919, \r
589                                         "height": 600, \r
590                                         "id": 9, \r
591                                         "updated_at": "2011-11-20T11:33:12Z", \r
592                                         "width": 800\r
593                                     },\r
594                                     {\r
595                                         "created_at": "2011-11-20T11:33:12Z", \r
596                                         "ext": "gif", \r
597                                         "filesize": 17919, \r
598                                         "height": 600, \r
599                                         "id": 10, \r
600                                         "updated_at": "2011-11-20T11:33:12Z", \r
601                                         "width": 800\r
602                                     },\r
603                                     {\r
604                                         "created_at": "2011-11-20T11:33:12Z", \r
605                                         "ext": "gif", \r
606                                         "filesize": 17919, \r
607                                         "height": 600, \r
608                                         "id": 11, \r
609                                         "updated_at": "2011-11-20T11:33:12Z", \r
610                                         "width": 800\r
611                                     },\r
612                                     {\r
613                                         "created_at": "2011-11-22T09:17:20Z", \r
614                                         "ext": "gif", \r
615                                         "filesize": 9055, \r
616                                         "height": 473, \r
617                                         "id": 12, \r
618                                         "updated_at": "2011-11-22T09:17:20Z", \r
619                                         "width": 405\r
620                                     }, \r
621                                     {\r
622                                         "created_at": "2011-11-22T10:11:07Z", \r
623                                         "ext": "gif", \r
624                                         "filesize": 8758, \r
625                                         "height": 464, \r
626                                         "id": 13, \r
627                                         "updated_at": "2011-11-22T10:11:07Z", \r
628                                         "width": 366\r
629                                     }, \r
630                                     {\r
631                                         "created_at": "2011-11-24T09:05:12Z", \r
632                                         "ext": "gif", \r
633                                         "filesize": 6431, \r
634                                         "height": 386, \r
635                                         "id": 16, \r
636                                         "updated_at": "2011-11-24T09:05:12Z", \r
637                                         "width": 453\r
638                                     }, \r
639                                     {\r
640                                         "created_at": "2011-11-26T04:52:12Z",\r
641                                         "ext": "gif", \r
642                                         "filesize": 6421, \r
643                                         "height": 426, \r
644                                         "id": 17, \r
645                                         "updated_at": "2011-11-26T04:52:12Z", \r
646                                         "width": 306\r
647                                     }, \r
648                                     {\r
649                                         "created_at": "2011-11-26T04:52:12Z",\r
650                                         "ext": "gif", \r
651                                         "filesize": 6421, \r
652                                         "height": 426, \r
653                                         "id": 18, \r
654                                         "updated_at": "2011-11-26T04:52:12Z", \r
655                                         "width": 306\r
656                                     }, \r
657                                     {\r
658                                         "created_at": "2011-11-26T04:52:12Z",\r
659                                         "ext": "gif", \r
660                                         "filesize": 6421, \r
661                                         "height": 426, \r
662                                         "id": 19, \r
663                                         "updated_at": "2011-11-26T04:52:12Z", \r
664                                         "width": 306\r
665                                     }, \r
666                                     {\r
667                                         "created_at": "2011-11-26T04:52:12Z",\r
668                                         "ext": "gif", \r
669                                         "filesize": 6421, \r
670                                         "height": 426, \r
671                                         "id": 20, \r
672                                         "updated_at": "2011-11-26T04:52:12Z", \r
673                                         "width": 306\r
674                                     }, \r
675                                     {\r
676                                         "created_at": "2011-11-26T04:52:12Z",\r
677                                         "ext": "gif", \r
678                                         "filesize": 6421, \r
679                                         "height": 426, \r
680                                         "id": 21, \r
681                                         "updated_at": "2011-11-26T04:52:12Z",\r
682                                         "width": 306\r
683                                     }\r
684                                 ]\r
685                         }\r
686                 \r
687                 var ImageGroupIconClass = function( INDEX, data){\r
688                         var JQ_ICON_WRAP = jqItemOrigin.clone( true),\r
689                                 SRC = [ BASE_PATH, data.id, '.', data.ext].join( ''),\r
690                                 LOW_SRC = data.filesize && data.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext].join( '') : null,\r
691                                 reversibleImage = null,\r
692                                 onEnterFlag = false;\r
693                         JQ_ICON_WRAP.children( 'div').eq( 0).html( data.filesize + 'bytes');\r
694                         jqContainer.append( JQ_ICON_WRAP.css( { left: INDEX * itemW}));\r
695                         \r
696                         return {\r
697                                 onEnter: function(){\r
698                                         if( onEnterFlag === true) return;\r
699                                         reversibleImage = pettanr.image.createReversibleImage( LOW_SRC || SRC, itemW, itemH, function( url, imgW, imgH){\r
700                                                 if( reversibleImage === null) {\r
701                                                         alert( url);\r
702                                                         return;\r
703                                                 }\r
704                                                 /*\r
705                                                  * ieでサイズが取れない、、、\r
706                                                  */\r
707                                                 imgW = imgW || data.width || 64;\r
708                                                 imgH = imgH || data.height || 64;\r
709                                                 JQ_ICON_WRAP.children( 'div').eq( 1).html( imgW +'x' +imgH);\r
710                                                 var zoom = 128 /( imgW > imgH ? imgW : imgH),\r
711                                                         h = Math.floor( imgH *zoom),\r
712                                                         w = Math.floor( imgW *zoom);\r
713                                                 reversibleImage.elm.style.width = w +'px';\r
714                                                 reversibleImage.elm.style.height = h +'px';\r
715                                                 reversibleImage.elm.style.margin = Math.floor( itemH /2 -h /2)+'px 0 0';\r
716                                                 reversibleImage.resize( w, h);\r
717                                                 JQ_ICON_WRAP.click( function( e){\r
718                                                         pettanr.overlay.hide();\r
719                                                         if (onUpdateFunction) {\r
720                                                                 if( LOW_SRC === null){\r
721                                                                         onUpdateFunction( SRC, imgW, imgH);\r
722                                                                 } else {\r
723                                                                         ( function( onUpdate){\r
724                                                                                 pettanr.util.loadImage( SRC,\r
725                                                                                         function( _abspath, imgW, imgH){\r
726                                                                                                 onUpdate( SRC, imgW, imgH);\r
727                                                                                                 onUpdate = null;\r
728                                                                                         },\r
729                                                                                         function( _abspath){\r
730                                                                                                 onUpdate( SRC, data.width || 64, data.height || 64);\r
731                                                                                                 onUpdate = null;\r
732                                                                                         }\r
733                                                                                 );                                                                              \r
734                                                                         })( onUpdateFunction); // close()で値が消えるので、クロージャに保持\r
735                                                                 }\r
736                                                         }\r
737                                                         close();\r
738                                                 });\r
739                                         });\r
740                                         JQ_ICON_WRAP.children( 'img').replaceWith( reversibleImage.elm);\r
741                                         onEnterFlag = true;                             \r
742                                 },\r
743                                 destroy: function(){\r
744                                         reversibleImage && reversibleImage.destroy();\r
745                                         JQ_ICON_WRAP.remove();\r
746                                         reversibleImage = JQ_ICON_WRAP = null;\r
747                                         delete this.destroy;\r
748                                 }\r
749                         }\r
750                 }\r
751                 \r
752                 function close(){\r
753                         jqContainer.stop().animate( {\r
754                                         height: 0,\r
755                                         top:    Math.floor( windowH /2)\r
756                                 }, function(){\r
757                                         jqWrap.hide()\r
758                                 });\r
759                         while( ICON_ARRAY.length > 0){\r
760                                 ICON_ARRAY.shift().destroy();\r
761                         }\r
762                         onEnterInterval !== null && window.clearTimeout( onEnterInterval);\r
763                         onUpdateFunction = onEnterInterval = null;\r
764                 }\r
765                 function onEnterShowImage(){\r
766                         var l = ICON_ARRAY.length,\r
767                                 _start = -wrapX /itemW -1,\r
768                                 _end = _start + winW /itemW +1;\r
769                         for( var i=0; i<l; ++i){\r
770                                 _start < i && i < _end && ICON_ARRAY[ i].onEnter();\r
771                         }\r
772                         onEnterInterval !== null && window.clearTimeout( onEnterInterval);\r
773                         onEnterInterval = null;\r
774                 }\r
775                 function clickOK(){\r
776                         pettanr.overlay.hide();\r
777                         // onUpdateFunction && onUpdateFunction( textElement);\r
778                         close();\r
779                 }\r
780                 return {\r
781                         init: function(){\r
782                                 this.jqWrap = jqWrap = $( '#image-gruop-wrapper').hide();\r
783                                 jqContainer = $( '#image-icon-container').mousewheel(\r
784                                         function( e, delta){\r
785                                                 if( winW < containerW){\r
786                                                         wrapX += delta *WHEEL_DELTA;\r
787                                                         wrapX = wrapX > 0 ? 0 : wrapX < winW -containerW ? winW -containerW : wrapX;\r
788                                                         jqContainer.css( { left: wrapX});\r
789                                                         \r
790                                                         onEnterInterval !== null && window.clearTimeout( onEnterInterval);\r
791                                                         onEnterInterval = window.setTimeout( onEnterShowImage, 500);\r
792                                                 }\r
793                                                 //e.stopPropagation();\r
794                                                 return false;\r
795                                         });\r
796                                 containerH = pettanr.util.getElementSize( jqContainer.get( 0)).height;\r
797                                 jqItemOrigin = $( $( '#imageGruopItemTemplete').remove().html());\r
798                                 var itemSize = pettanr.util.getElementSize( jqItemOrigin.get( 0));\r
799                                 itemW = itemSize.width;\r
800                                 itemH = itemSize.height;\r
801                                 jqName = $( '#gruop-name-display');\r
802                                 jqButton = $( '#image-gruop-button').click( clickOK);\r
803                                 buttonW = pettanr.util.getElementSize( jqButton.get( 0)).width;\r
804                                 \r
805                                 delete IMAGE_GROUP_EXPROLER.init;\r
806                         },\r
807                         jqWrap: null,\r
808                         show: function( _onUpdateFunction){\r
809                                 onUpdateFunction = _onUpdateFunction;\r
810                                 pettanr.overlay.show( this);\r
811                                 \r
812                                 var CURRENT_GROUP_ARRAY = IMAGE_DATA[ 'pen001'] || [],\r
813                                         l = CURRENT_GROUP_ARRAY.length;\r
814                                 for( var i=0; i<l; ++i){\r
815                                         ICON_ARRAY.push( ImageGroupIconClass.apply( {}, [ i, CURRENT_GROUP_ARRAY[ i]]));\r
816                                 }\r
817                                 wrapX = 0;\r
818                                 containerW = l * itemW;\r
819                                 \r
820                                 winW = windowW;\r
821                                 var w = winW > containerW ? winW : containerW,\r
822                                         h = windowH > containerH ? containerH : windowH;\r
823                                 \r
824                                 jqWrap.show();\r
825                                 jqContainer.css( {\r
826                                         width:          w,\r
827                                         height:         0,\r
828                                         left:           0,\r
829                                         top:            Math.floor( windowH /2)\r
830                                 }).stop().animate( {\r
831                                         height:         h,\r
832                                         top:            Math.floor( windowH /2 -h /2)\r
833                                 });\r
834                                 \r
835                                 jqButton.css( {\r
836                                         left:           Math.floor( winW /2 -buttonW /2),\r
837                                         top:            Math.floor( windowH /2 +containerH /2 +10)\r
838                                 });\r
839                                 \r
840                                 onEnterShowImage();\r
841                         },\r
842                         onWindowResize: function( _windowW, _windowH){\r
843                                 var w = _windowW > containerW ? _windowW : containerW,\r
844                                         h = _windowH > containerH ? containerH : _windowH,\r
845                                         offsetW = Math.floor( _windowW /2 -winW /2);\r
846                                 winW = _windowW;\r
847                                 if( offsetW <= 0){ // smaller\r
848                                         jqContainer.css( {\r
849                                                 left:                           offsetW,\r
850                                                 width:                          w\r
851                                         }).animate( {\r
852                                                 left:                           0,\r
853                                                 top:                            Math.floor( _windowH /2 -h /2)\r
854                                         });                                     \r
855                                 } else {\r
856                                         jqContainer.css( { // bigger\r
857                                                 left:                           0,\r
858                                                 width:                          w,\r
859                                                 borderLeftWidth:        offsetW\r
860                                         }).animate( {\r
861                                                 top:                            Math.floor( _windowH /2 -h /2),\r
862                                                 borderLeftWidth:        0\r
863                                         });\r
864                                 }\r
865                                 jqButton.css( {\r
866                                         left:           Math.floor( _windowW /2 -buttonW /2),\r
867                                         top:            Math.floor( _windowH /2 +containerH /2 +10)\r
868                                 });\r
869                                 onEnterShowImage();\r
870                         },\r
871                         onClose: close,\r
872                         ID: 'imageGroupExproler'\r
873                 }\r
874         })();\r
875 \r
876 /* ----------------------------------------\r
877  * WINDOWS_CONTROL\r
878  */     \r
879         var WINDOWS_CONTROL = ( function(){\r
880                 /*\r
881                  *  表示上手前にあるwindowは、WINDOW_ARRAYの先頭にあり、htmlでは後ろにある。\r
882                  */\r
883                 var DEFAULT_MIN_WINDOW_WIDTH = 200,\r
884                         DEFAULT_MIN_WINDOW_HEIGHT = 200,\r
885                         WINDOW_ARRAY = [],\r
886                         WINDOW_BODY_BODER_SIZE = 1,\r
887                         jqContainer,\r
888                         currentWindow,\r
889                         currentWindowIndex = -1,\r
890                         log;\r
891 \r
892                 var jqWindowOrigin,\r
893                         closeButtonWidth;\r
894                 var WindowClass = function( bodyTempleteID, title, x, y, w, h, visible, CLOSE_BUTTON_ENABLED, RESIZE_BUTTON_ENABLED, minWindowW, minWindowH){\r
895                         var MOUSE_CURSOR = updateMouseCursor,\r
896                                 MENUBAR_SELWCTION = MENU_BAR_CONTROL.WINDOW.createSelection( \r
897                                         ( visible !== true ? 'show ' : 'hide ') +title,\r
898                                         null, onMenuClick, true\r
899                                 ),\r
900                                 jqStage,\r
901                                 jqWrapper, jqHeader, elmBody, elmBodyStyle,\r
902                                 startX, startY, startW, startH,\r
903                                 xOffset, yOffset,\r
904                                 headerH, bodyH,\r
905                                 isDragging = false,\r
906                                 isResizing = false,\r
907                                 bodyIsTachable = false,\r
908                                 instance;\r
909 \r
910                         function onMenuClick(){\r
911                                 visible === true ? instance.close() : instance.open();\r
912                         }\r
913                         function update( _x, _y, _w, _h){\r
914                                 ( w !== _w || h !== _h) && instance.onResize && instance.onResize( _w, _h);\r
915                                 x = _x !== undefined ? _x : x;\r
916                                 y = _y !== undefined ? _y : y;\r
917                                 w = _w !== undefined ? _w : w;\r
918                                 h = _h !== undefined ? _h : h;\r
919                                 y = y > MENU_BAR_CONTROL.h ? y : MENU_BAR_CONTROL.h;\r
920                                 jqWrapper.css( {\r
921                                         left:           x,\r
922                                         top:            y,\r
923                                         width:          w,\r
924                                         height:         h\r
925                                 });\r
926                                 bodyH = h -headerH;\r
927                                 elmBodyStyle.height = bodyH +'px';\r
928                         }\r
929                         function bodyBackOrForward( isBack){\r
930                                 if( !instance) return;\r
931                                 if( bodyIsTachable === !isBack) return;\r
932                                 elmBodyStyle.position = isBack === true ? 'relative' : 'absolute';\r
933                                 elmBodyStyle.left =             isBack === true ? 0  : x +'px';\r
934                                 elmBodyStyle.top =              isBack === true ? 0  : y +headerH +'px';\r
935                                 elmBodyStyle.width =    isBack === true ? '' : ( w -WINDOW_BODY_BODER_SIZE *2) +'px';\r
936                                 bodyIsTachable === isBack && isBack === true ? jqWrapper.append( elmBody) : jqStage.append( elmBody);\r
937                                 bodyIsTachable = !isBack;\r
938                         }\r
939                         function onWindowResize( e){\r
940                                 bodyBackOrForward( true);\r
941                                 isResizing = true;\r
942                                 startX = x;\r
943                                 startY = y;\r
944                                 startW = w;\r
945                                 startH = h;\r
946                                 xOffset = e.pageX;\r
947                                 yOffset = e.pageY;\r
948                                 MOUSE_CURSOR( 'nw-resize');\r
949                                 e.stopPropagation();\r
950                                 return false;\r
951                         }\r
952                         return {\r
953                                 init: function( jqContainer){\r
954                                         /*\r
955                                          * setTimeout で呼ばれるグローバルメソッドは、this でなく instance を使う.\r
956                                          */\r
957                                         instance = this;\r
958                                         \r
959                                         jqWindowOrigin = jqWindowOrigin || ( function(){\r
960                                                 return $( $( '#windowTemplete').remove().html());\r
961                                         })();\r
962                                         closeButtonWidth = closeButtonWidth || ( function(){\r
963                                                 return pettanr.util.getElementSize( jqWindowOrigin.clone( true).find( '.window-close-button').get( 0)).width;\r
964                                         })();\r
965                                         \r
966                                         jqStage = jqEditor;\r
967                                         this.$ = jqWrapper = jqWindowOrigin.clone( true);\r
968                                         jqHeader = jqWrapper.children( '.window-header').eq( 0).html( title);\r
969                                         headerH = pettanr.util.getElementSize( jqHeader.get( 0)).height;\r
970                                         elmBody = jqWrapper.children( '.window-body').get( 0);\r
971                                         elmBodyStyle = elmBody.style;\r
972                                         if( bodyTempleteID) {\r
973                                                 jqWrapper.find( '.window-body-insert-position').replaceWith( $( $( '#' +bodyTempleteID).remove().html()));\r
974                                         } else {\r
975                                                 jqWrapper.find( '.window-body-insert-position').remove();\r
976                                         }\r
977                                         CLOSE_BUTTON_ENABLED !== true && jqWrapper.find( '.window-close-button').remove();\r
978                                         \r
979                                         this.onInit && this.onInit();\r
980                                         delete this.init;\r
981                                 },\r
982                                 x: function(){ return x;},\r
983                                 y: function(){ return y;},\r
984                                 w: function(){ return w;},\r
985                                 h: function(){ return h;},\r
986                                 $: null,\r
987                                 title: function( _title){\r
988                                         _title !== undefined && jqHeader.html( _title);\r
989                                         title = _title || title;\r
990                                         return title;\r
991                                 },\r
992                                 visible: visible,\r
993                                 firstOpen: function(){\r
994                                         if( RESIZE_BUTTON_ENABLED === true){\r
995                                                 jqWrapper.find( '.window-resize-button').eq( 0).mousedown( onWindowResize);\r
996                                         } else {\r
997                                                 jqWrapper.find( '.window-resize-button').remove();\r
998                                         }\r
999                                         update( x, y, w, h);\r
1000                                         \r
1001                                         this.onFirstOpen && this.onFirstOpen();\r
1002                                         \r
1003                                         delete this.firstOpen;\r
1004                                 },\r
1005                                 open: function(){\r
1006                                         if( visible === true) return;\r
1007                                         instance.visible = visible = true;\r
1008                                         openWindow( instance);\r
1009                                         MENUBAR_SELWCTION.title( 'hide ' +title);\r
1010                                         \r
1011                                         for( var i=0, l = WINDOW_ARRAY.length; i<l; ++i){\r
1012                                                 if( WINDOW_ARRAY[ i] === instance){\r
1013                                                         WINDOW_ARRAY.splice( i, 1);\r
1014                                                         WINDOW_ARRAY.unshift( instance);\r
1015                                                         currentWindow = null;\r
1016                                                         currentWindowIndex = -1;\r
1017                                                 }\r
1018                                         }\r
1019                                 },\r
1020                                 close: function(){\r
1021                                         if( visible === false) return;\r
1022                                         instance.visible = visible = false;\r
1023                                         instance.onClose && setTimeout( instance.onClose, 0);\r
1024                                         closeWindow( instance);\r
1025                                         MENUBAR_SELWCTION.title( 'show ' +title);\r
1026                                 },\r
1027                                 bodyBackOrForward: bodyBackOrForward,\r
1028                                 onMouseDown: function( _mouseX, _mouseY){\r
1029                                         if( x > _mouseX || y > _mouseY || x +w < _mouseX || y +headerH < _mouseY ) return;\r
1030                                         if( CLOSE_BUTTON_ENABLED === true && x +w -closeButtonWidth < _mouseX){\r
1031                                                 this.close();\r
1032                                                 return;\r
1033                                         }\r
1034                                         isDragging = true;\r
1035                                         MOUSE_CURSOR( 'move');                          \r
1036                                         startX = x;\r
1037                                         startY = y;\r
1038                                         startW = w;\r
1039                                         startH = h;\r
1040                                         xOffset = _mouseX;\r
1041                                         yOffset = _mouseY;\r
1042                                 },\r
1043                                 onMouseUp: function( _mouseX, _mouseY){\r
1044                                         isDragging = isResizing = false;\r
1045                                         MOUSE_CURSOR( '');\r
1046                                 },\r
1047                                 onMouseMove: function( _mouseX, _mouseY){\r
1048                                         var _updateX = _mouseX -xOffset,\r
1049                                                 _updateY = _mouseY -yOffset;\r
1050                                         \r
1051                                         if( isResizing === true){\r
1052                                                 var _w = startW +_updateX,\r
1053                                                         _h = startH +_updateY;\r
1054                                                 update( startX, startY, _w < minWindowW ? minWindowW : _w, _h < minWindowH ? minWindowH : _h);\r
1055                                                 return;\r
1056                                         } else\r
1057                                         if( isDragging === true) {\r
1058                                                 update( startX +_updateX, startY +_updateY);\r
1059                                                 return;\r
1060                                         } else\r
1061                                         if( x > _mouseX || x +w < _mouseX ) return;\r
1062         \r
1063                                         ( y <= _mouseY && y +headerH >= _mouseY ) ?\r
1064                                                 MOUSE_CURSOR( 'pointer') :      // hit to header\r
1065                                                 MOUSE_CURSOR( '');\r
1066                                         bodyBackOrForward( y +headerH > _mouseY || y +headerH +bodyH < _mouseY);\r
1067                                 },\r
1068                                 onMouseOut: function( _mouseX, _mouseY){\r
1069                                         bodyIsTachable === true && bodyBackOrForward( true);\r
1070                                         isDragging = false;\r
1071                                         MOUSE_CURSOR( '');\r
1072                                 },\r
1073                                 busy: function(){\r
1074                                         return isDragging === true || isResizing === true;\r
1075                                 },\r
1076                                 bodyHeight: function(){\r
1077                                         return  bodyH;\r
1078                                 }\r
1079                         }\r
1080                 };\r
1081                 \r
1082                 function getCurrentWindow( _mouseX, _mouseY){\r
1083                         if( currentWindow && currentWindow.busy() === true) return currentWindowIndex;\r
1084                         var l = WINDOW_ARRAY.length,\r
1085                                 _currentWindow = null,\r
1086                                 _win, _x, _y;\r
1087                         currentWindowIndex = -1;\r
1088                         for( var i=0; i<l; i++){\r
1089                                 _win = WINDOW_ARRAY[ i];\r
1090                                 if( _win.visible !== true) continue;\r
1091                                 _x = _win.x();\r
1092                                 _y = _win.y();\r
1093                                 if( _x <= _mouseX && _y <= _mouseY && _x +_win.w() >= _mouseX && _y +_win.h() >= _mouseY){\r
1094                                         _currentWindow = _win;\r
1095                                         currentWindowIndex = i;\r
1096                                         break;\r
1097                                 }\r
1098                         }\r
1099                         currentWindow && currentWindow !== _currentWindow && currentWindow.onMouseOut( _mouseX, _mouseY);\r
1100                         currentWindow = _currentWindow;\r
1101                         return currentWindowIndex;\r
1102                 }\r
1103                 function openWindow( _window){\r
1104                         if( _window.visible !== true) return;\r
1105                         var _jqWindow = _window.$;\r
1106                         jqContainer.append( _jqWindow);// appendした後に fadeIn() しないと ie で filterが適用されない.\r
1107                         _jqWindow.fadeIn(\r
1108                                 function(){\r
1109                                         _window.firstOpen && _window.firstOpen();\r
1110                                         _window.onOpen && setTimeout( _window.onOpen, 0);\r
1111                                 }\r
1112                         );\r
1113                         return;\r
1114                 }\r
1115                 function closeWindow( _window){\r
1116                         if( _window.visible !== false) return;\r
1117                         var l = WINDOW_ARRAY.length;\r
1118                         for( var i=0; i<l; ++i){\r
1119                                 if( WINDOW_ARRAY[ i] === _window){\r
1120                                         //WINDOW_ARRAY.splice( i, 1);\r
1121                                         //WINDOW_ARRAY.push( _window);\r
1122                                         _window.$.stop().fadeOut( function(){\r
1123                                                 this.parentNode.removeChild( this);\r
1124                                         });\r
1125                                         return;\r
1126                                 }\r
1127                         }\r
1128                 }\r
1129                 \r
1130                 return {\r
1131                         init: function(){\r
1132                                 jqContainer = $( '#window-container');\r
1133                                 \r
1134                                 var l = WINDOW_ARRAY.length,\r
1135                                         _window;\r
1136                                 for( var i=l-1; i >= 0; --i){\r
1137                                         _window = WINDOW_ARRAY[ i];\r
1138                                         _window.init && _window.init( jqContainer);\r
1139                                         _window.visible === true && openWindow( _window);\r
1140                                 }\r
1141                                 log = $( '#window-log');\r
1142                                 \r
1143                                 delete WINDOWS_CONTROL.init;\r
1144                         },\r
1145                         onMouseMove: function( _mouseX, _mouseY){\r
1146                                 var _index = getCurrentWindow( _mouseX, _mouseY);\r
1147                                 if( _index === 0){\r
1148                                         currentWindow.onMouseMove( _mouseX, _mouseY);\r
1149                                         return true;\r
1150                                 } else\r
1151                                 if( _index !== -1){ // 先頭のクリックでない場合\r
1152                                 // Array を前に\r
1153                                         WINDOW_ARRAY.splice( currentWindowIndex, 1);\r
1154                                         WINDOW_ARRAY.unshift( currentWindow);\r
1155                                 // Domを最後に\r
1156                                         jqContainer.append( currentWindow.$);\r
1157                                         currentWindowIndex = 0;\r
1158                                         return true;\r
1159                                 }\r
1160                                 return false;\r
1161                         },\r
1162                         onMouseUp: function( _mouseX, _mouseY){\r
1163                                 if( getCurrentWindow( _mouseX, _mouseY) === 0){\r
1164                                         currentWindow.onMouseUp( _mouseX, _mouseY);\r
1165                                         return true;\r
1166                                 }\r
1167                                 return false;\r
1168                         },\r
1169                         onMouseDown: function( _mouseX, _mouseY){\r
1170                                 if( getCurrentWindow( _mouseX, _mouseY) === 0){\r
1171                                         currentWindow.onMouseDown( _mouseX, _mouseY);\r
1172                                         return true;\r
1173                                 }\r
1174                                 return false;\r
1175                         },\r
1176                         busy: function(){\r
1177                                 return currentWindow !== null;\r
1178                         },\r
1179                         onWindowResize: function( _windowW, _windowH){\r
1180                                 /*\r
1181                                  * 画面外に出るwindowの移動\r
1182                                  */\r
1183                         },\r
1184                         createWindow: function( scope, EXTENDS, bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeButtonEnabled, opt_resizeButtonEnabled, opt_minWindowW, opt_minWindowH){\r
1185                                 opt_visible = opt_visible !== false;\r
1186                                 opt_closeButtonEnabled = opt_closeButtonEnabled === true;\r
1187                                 opt_resizeButtonEnabled = opt_resizeButtonEnabled === true;\r
1188                                 opt_minWindowW = opt_minWindowW || ( w < DEFAULT_MIN_WINDOW_WIDTH) ? w : DEFAULT_MIN_WINDOW_WIDTH;\r
1189                                 opt_minWindowH = opt_minWindowH || ( h < DEFAULT_MIN_WINDOW_HEIGHT) ? h : DEFAULT_MIN_WINDOW_HEIGHT;\r
1190                                 \r
1191                                 var _window = pettanr.util.extend(\r
1192                                         WindowClass.apply( scope, [ bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeButtonEnabled, opt_resizeButtonEnabled, opt_minWindowW, opt_minWindowH]),\r
1193                                         EXTENDS\r
1194                                 );\r
1195                                 WINDOW_ARRAY.unshift( _window);\r
1196                                 WINDOWS_CONTROL.init === undefined && _window.init( jqContainer);\r
1197                                 WINDOWS_CONTROL.init === undefined && openWindow( _window);\r
1198                                 return _window;\r
1199                         }\r
1200                 }\r
1201         })();\r
1202 \r
1203 /* ----------------------------------------\r
1204  * TOOL_BOX_WINDOW\r
1205  */\r
1206         var TOOL_BOX_WINDOW = ( function(){\r
1207                 var addImageButton, addTextButton, editBgButton, switchGridButton, popupHelpButton, postButton,\r
1208                         gridSwitchFunction,\r
1209                         instance;\r
1210                         \r
1211                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 73, false, true, addImage);\r
1212                 MENU_BAR_CONTROL.EDIT.createSelection( 'Add Image', 'ctrl + I', addImage, true, true, false);\r
1213                 \r
1214                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 84, false, true, addText);\r
1215                 MENU_BAR_CONTROL.EDIT.createSelection( 'Add Text', 'ctrl + T', addText, true, false, true);\r
1216 \r
1217                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 71, false, true, switchGrid);\r
1218                 MENU_BAR_CONTROL.EDIT.createSelection( 'show Grid', 'ctrl + G', switchGrid, true, true, true);\r
1219 \r
1220                 function addImage( e){\r
1221                         setTimeout( COMIC_ELEMENT_CONTROL.createImageElement, 0);\r
1222                         e && e.preventDefault();\r
1223                         return false;\r
1224                 }\r
1225                 function addText( e){\r
1226                         setTimeout( COMIC_ELEMENT_CONTROL.createTextElement, 0);\r
1227                         e && e.preventDefault();\r
1228                         return false;\r
1229                 }\r
1230                 function switchGrid( e){\r
1231                         setTimeout( gridSwitchFunction, 0);\r
1232                         e && e.preventDefault();\r
1233                         return false;\r
1234                 }\r
1235                 function popupHelp( e){\r
1236                         instance.bodyBackOrForward( true);\r
1237                         setTimeout( HELP_DOCUMENTS_WINDOW.open, 0);\r
1238                         e && e.preventDefault();\r
1239                         return false;\r
1240                 }\r
1241                 function editBG( e){\r
1242                         instance.bodyBackOrForward( true);\r
1243                         setTimeout( INFOMATION_WINDOW.open, 0); \r
1244                         e && e.preventDefault();\r
1245                         return false;\r
1246                 }\r
1247                 \r
1248                 return WINDOWS_CONTROL.createWindow(\r
1249                         this,\r
1250                         {\r
1251                                 onInit: function(){\r
1252                                         instance = this;\r
1253                                         delete this.onInit;\r
1254                                 },\r
1255                                 onFirstOpen: function(){\r
1256                                         addImageButton = $( '#toolbox-add-image-button').click( addImage);\r
1257                                         addTextButton = $( '#toolbox-add-text-button').click( addText);\r
1258                                         editBgButton = $( '#toolbox-edit-bg-button').click( editBG);\r
1259                                         switchGridButton = $( '#toolbox-switch-grid').click( switchGrid);\r
1260                                         popupHelpButton = $( '#toolbox-popup-help-button').click( popupHelp);\r
1261                                         \r
1262                                         postButton = $( '#toolbox-post-button');\r
1263                                         \r
1264                                         delete this.onFirstOpen;\r
1265                                 },\r
1266                                 setGridSwitchFunction: function( _gridSwitchFunction){\r
1267                                         gridSwitchFunction = _gridSwitchFunction || gridSwitchFunction;\r
1268                                 }\r
1269                         },\r
1270                         'toolbox-window', 'Tool box', 0, 215, 110, 290, true\r
1271                 );\r
1272         })();\r
1273 /* ----------------------------------------\r
1274  * INFOMATION_WINDOW\r
1275  */                     \r
1276         var INFOMATION_WINDOW = ( function(){\r
1277                 var FADE_EFFECT_ENABLED = pettanr.ua.isIE === false || pettanr.ua.ieVersion >= 8,\r
1278                         FADE_IN_EFFECT = FADE_EFFECT_ENABLED === true ? 'fadeIn' : 'show',\r
1279                         FADE_OUT_EFFECT = FADE_EFFECT_ENABLED === true ? 'fadeOut' : 'hide',\r
1280                         backgroundInfomationElm,\r
1281                         jqComicElementInformation,\r
1282                         elmValueX, elmValueY, elmValueZ, elmValueA, elmValueW, elmValueH, elmAspect,\r
1283                         elmPercentW, elmPercentH,\r
1284                         currentComicElement = null,\r
1285                         currentElementType = -1;\r
1286 \r
1287                 return WINDOWS_CONTROL.createWindow(\r
1288                         this,\r
1289                         {\r
1290                                 onFirstOpen: function(){\r
1291                                         backgroundInfomationElm = $( '#panel-background-information');\r
1292                                         \r
1293                                         jqComicElementInformation = $( '#comic-element-infomation').hide().css( {\r
1294                                                 height:         this.bodyHeight()\r
1295                                         });\r
1296                                         var TAB_GROUP_ID = 'comic-element-attribute';\r
1297                                         var CREATER = pettanr.key.createEditableText;\r
1298                                         elmValueX = CREATER( $( '#comic-element-x'), null, TAB_GROUP_ID);\r
1299                                         elmValueY = CREATER( $( '#comic-element-y'), null, TAB_GROUP_ID);\r
1300                                         elmValueZ = CREATER( $( '#comic-element-z'), null, TAB_GROUP_ID);\r
1301                                         elmValueA = CREATER( $( '#comic-element-a'), null, TAB_GROUP_ID);\r
1302                                         elmValueW = CREATER( $( '#comic-element-w'), null, TAB_GROUP_ID);\r
1303                                         elmValueH = CREATER( $( '#comic-element-h'), null, TAB_GROUP_ID);\r
1304                                         elmPercentW = CREATER( $( '#comic-element-w-percent'), null, TAB_GROUP_ID);\r
1305                                         elmPercentH = CREATER( $( '#comic-element-h-percent'), null, TAB_GROUP_ID);\r
1306                                         elmAspect = $( '#comic-element-keep-aspect');\r
1307                                         delete this.onFirstOpen;\r
1308                                 },\r
1309                                 onResize: function( w, h){\r
1310                                         jqComicElementInformation && jqComicElementInformation.css( {\r
1311                                                 height: this.bodyHeight()\r
1312                                         });\r
1313                                 },\r
1314                                 update: function( _elementType, x, y, z, a, w, h, wPercent, hPercent, keepAspect){\r
1315                                         if( !backgroundInfomationElm) return; // なぜか !backgroundInfomationElm が必要\r
1316                                         if( currentElementType !== _elementType){\r
1317                                                 if( _elementType !== -1){\r
1318                                                         if( _elementType === 1){\r
1319                                                                 elmValueA.show();\r
1320                                                                 elmPercentW.hide();\r
1321                                                                 elmPercentH.hide();\r
1322                                                                 elmAspect.hide();\r
1323                                                         } else {\r
1324                                                                 elmValueA.hide();\r
1325                                                                 elmPercentW.show();\r
1326                                                                 elmPercentH.show();\r
1327                                                                 elmAspect.show();\r
1328                                                         }\r
1329                                                         currentElementType === -1 && jqComicElementInformation.stop().css( {\r
1330                                                                 filter:         '',\r
1331                                                                 opacity:        ''\r
1332                                                         })[ FADE_IN_EFFECT]();\r
1333                                                 } else {\r
1334                                                         currentElementType !== -1 && jqComicElementInformation.stop().css({\r
1335                                                                 filter:         '',\r
1336                                                                 opacity:        ''\r
1337                                                         })[ FADE_OUT_EFFECT]();\r
1338                                                 }\r
1339                                                 currentElementType = _elementType;\r
1340                                         }\r
1341                                         if( currentElementType !== -1){\r
1342                                                 elmValueX.update( x);\r
1343                                                 elmValueY.update( y);\r
1344                                                 elmValueZ.update( z);\r
1345                                                 _elementType === 1 && elmValueA.update( a);\r
1346                                                 elmValueW.update( w);\r
1347                                                 elmValueH.update( h);\r
1348                                                 _elementType === 0 && elmPercentW.update( wPercent);\r
1349                                                 _elementType === 0 && elmPercentH.update( hPercent);                                    \r
1350                                         } else {\r
1351                                                 \r
1352                                         }\r
1353                                 }\r
1354                         },\r
1355                         'infomation-window', 'Infomation', 0, 30, 200, 180, true\r
1356                 );\r
1357         })();\r
1358 \r
1359 /* ----------------------------------------\r
1360  * HELP_WINDOW\r
1361  */\r
1362         var HELP_DOCUMENTS_WINDOW = ( function(){\r
1363                 var visible = true,\r
1364                         hasAjaxContents = false,\r
1365                         jqAjaxContents,\r
1366                         jqNaviItems,\r
1367                         jqPages,\r
1368                         HELP = MENU_BAR_CONTROL.HELP,\r
1369                         onLoadFunction = HELP.createAjaxSelection( onFirstOpen),\r
1370                         instance;\r
1371                 function jumpPage( _index){\r
1372                         \r
1373                 }\r
1374                 function onFirstOpen( _pageIndex){\r
1375                         _pageIndex = _pageIndex || 0;\r
1376                         if( hasAjaxContents === false){\r
1377                                 $.ajax({\r
1378                                         url:            'help/jp.xml',\r
1379                                         dataType:       'xml',\r
1380                                         success:        function( _xml){\r
1381                                                 var jqXML = $( _xml),\r
1382                                                         helpTitle = jqXML.find( 'pages').eq( 0).attr( 'title'),\r
1383                                                         elmNavi = document.createElement( 'DIV'),\r
1384                                                         elmItemOrigin = document.createElement( 'A'),\r
1385                                                         elmPages = document.createElement( 'DIV'),\r
1386                                                         elmPageOrigin = document.createElement( 'DIV'),\r
1387                                                         elmTitleOrigin = document.createElement( 'H2'),\r
1388                                                         elmPage,\r
1389                                                         numPage = 0;\r
1390                                                 elmNavi.className = 'sidenavi';\r
1391                                                 elmItemOrigin.className = 'sidenavi-item';\r
1392                                                 elmItemOrigin.href = '#';\r
1393                                                 elmPages.className = 'page-contents';\r
1394                                                 elmPageOrigin.className = 'page-content';\r
1395                                                 elmPageOrigin.appendChild( elmTitleOrigin);\r
1396                                                 \r
1397                                                 // helpTitle && instance.title( helpTitle);\r
1398                                                 \r
1399                                                 jqXML.find( 'page').each( function(){\r
1400                                                         var xmlPage = $( this),\r
1401                                                                 title = xmlPage.attr( 'title'),\r
1402                                                                 content = xmlPage.text();\r
1403                                                         \r
1404                                                         elmItemOrigin.innerHTML = title;\r
1405                                                         elmNavi.appendChild( elmItemOrigin.cloneNode( true));\r
1406                                                         \r
1407                                                         elmTitleOrigin.innerHTML = title;\r
1408                                                         elmPage = elmPageOrigin.cloneNode( true);\r
1409                                                         elmPage.innerHTML = content;\r
1410                                                         \r
1411                                                         pettanr.util.cleanElement( elmPage);\r
1412                                                         \r
1413                                                         if( elmPage.childNodes.length > 0){\r
1414                                                                 elmPage.insertBefore( elmTitleOrigin.cloneNode( true), elmPage.childNodes[0]);\r
1415                                                         } else {\r
1416                                                                 elmPage.appendChild( elmTitleOrigin.cloneNode( true));\r
1417                                                         }\r
1418                                                         elmPages.appendChild( elmPage);\r
1419                                                         \r
1420                                                         HELP.createSelection( title, null, ( function( _pageIndex){\r
1421                                                                 return function(){\r
1422                                                                         HELP_DOCUMENTS_WINDOW.open();\r
1423                                                                         onOpen( _pageIndex);                                                                    \r
1424                                                                 }\r
1425                                                         })( numPage), true);\r
1426                                                         ++numPage;\r
1427                                                 });\r
1428                                                 onLoadFunction();\r
1429                                                 onLoadFunction = null;\r
1430                                                 \r
1431                                                 jqAjaxContents.removeClass( 'loading').append( elmNavi, elmPages);\r
1432                                                 \r
1433                                                 jqNaviItems = jqAjaxContents.find( 'a.' +elmItemOrigin.className)\r
1434                                                         .click( function( e){\r
1435                                                                 var that = this,\r
1436                                                                         parent = this.parentNode,\r
1437                                                                         i = ( function(){\r
1438                                                                                 var children = parent.getElementsByTagName( 'A'),\r
1439                                                                                         l = children.length;\r
1440                                                                                 for( var i=0; i<l; ++i){\r
1441                                                                                         if( children[ i] === that) return i;\r
1442                                                                                 }\r
1443                                                                                 return -1;\r
1444                                                                         })();\r
1445                                                                 e.stopPropagation();\r
1446                                                                 if( i === -1) return false;\r
1447                                                                 jqNaviItems.removeClass( 'current').eq( i).addClass( 'current');\r
1448                                                                 jqPages.hide().eq( i).show();\r
1449                                                                 \r
1450                                                                 return false;\r
1451                                                         });\r
1452                                                 jqAjaxContents.find( '.' +elmPageOrigin.className).find( 'a')\r
1453                                                         .click( function( e){\r
1454                                                                 var that = this,\r
1455                                                                         i = ( function(){\r
1456                                                                                 var href = that.href,\r
1457                                                                                         i = href.split( '#jump'),\r
1458                                                                                         n = i[1]\r
1459                                                                                 if( n && '' +parseFloat( n) === n){\r
1460                                                                                         return parseFloat( n)\r
1461                                                                                 }\r
1462                                                                                 return -1;\r
1463                                                                         })();\r
1464                                                                 e.stopPropagation();\r
1465                                                                 if( i === -1) return false;\r
1466                                                                 jqNaviItems.removeClass( 'current').eq( i).addClass( 'current');\r
1467                                                                 jqPages.hide().eq( i).show();\r
1468                                                                 \r
1469                                                                 return false;\r
1470                                                         });\r
1471                                                 jqNaviItems.eq( _pageIndex).addClass( 'current');\r
1472                                                 jqPages = jqAjaxContents.find( '.page-content');\r
1473                                                 jqPages.eq( _pageIndex).show();\r
1474                                         }\r
1475                                 });\r
1476                                 hasAjaxContents = true;\r
1477                         }\r
1478                         function onOpen( _pageIndex){\r
1479                                 _pageIndex = _pageIndex || 0;\r
1480                                 jqNaviItems.removeClass( 'current').eq( _pageIndex).addClass( 'current');\r
1481                                 jqPages.hide().eq( _pageIndex).show();\r
1482                         }\r
1483                 }\r
1484                 return WINDOWS_CONTROL.createWindow(\r
1485                         this,\r
1486                         {\r
1487                                 onInit: function(){\r
1488                                         instance = this;\r
1489                                         jqAjaxContents = this.$.find( '.window-body').addClass( 'loading').css( { height: this.bodyHeight()});\r
1490                                         delete this.onInit;\r
1491                                 },\r
1492                                 onFirstOpen: onFirstOpen,\r
1493                                 onResize: function( w, h){\r
1494                                         jqAjaxContents && jqAjaxContents.css( { height: this.bodyHeight()});\r
1495                                 },\r
1496                                 setAjaxContent: function( html){\r
1497                                         \r
1498                                         delete this.onLoadAjaxContent;\r
1499                                 }\r
1500                         },\r
1501                         null, 'Help', 0, 215, 400, 350, false, true, true, 300, 300\r
1502                 );\r
1503         })();\r
1504 \r
1505 /* ----------------------------------------\r
1506  * GRID_CONTROL\r
1507  */\r
1508         var GRID_CONTROL = ( function(){\r
1509                 var elmGrid = document.getElementById( 'grid'),\r
1510                         jQGrid,\r
1511                         visible = false;\r
1512                 \r
1513                 function update(){\r
1514                         jQGrid.css( {\r
1515                                 opacity:        '',\r
1516                                 fliter:         ''\r
1517                         }).stop()[ visible === true ? 'fadeOut' : 'fadeIn']();\r
1518                         visible = !visible;\r
1519                         if( visible === true && !elmGrid.style.backgroundImage){\r
1520                                 elmGrid.style.backgroundImage = "url('grid.gif')";\r
1521                         }\r
1522                         return visible;\r
1523                 }\r
1524                 return {\r
1525                         init: function(){\r
1526                                 jQGrid = $( elmGrid);\r
1527                                 TOOL_BOX_WINDOW.setGridSwitchFunction( update);\r
1528                                 delete GRID_CONTROL.init;\r
1529                         },\r
1530                         onCanvasResize: function( _canvasX, _canvasY){\r
1531                                 elmGrid.style.backgroundPosition = [ _canvasX % 10, 'px ', _canvasY % 10, 'px'].join( '');\r
1532                                 elmGrid.style.height = windowH +'px';\r
1533                         },\r
1534                         enabled: function(){\r
1535                                 return visible;\r
1536                         }\r
1537                 }\r
1538         })();\r
1539                 \r
1540         /*\r
1541          *      WHITE_GLASS_CONTROL\r
1542          */     \r
1543         var WHITE_GLASS_CONTROL = ( function(){\r
1544                 var styleTop = document.getElementById( 'whiteGlass-top').style,\r
1545                         styleLeft = document.getElementById( 'whiteGlass-left').style,\r
1546                         styleRight = document.getElementById( 'whiteGlass-right').style,\r
1547                         styleBottom = document.getElementById( 'whiteGlass-bottom').style;\r
1548                 function resize( _canvasX, _canvasY, _canvasW, _canvasH){\r
1549                         var     _w = _canvasW,\r
1550                                 _h = _canvasH,\r
1551                                 marginTop = _canvasY,\r
1552                                 marginBottom = windowH -_h -marginTop,\r
1553                                 marginX = _canvasX,\r
1554                                 rightWidth = windowW -_w -marginX;\r
1555                         \r
1556                         styleTop.height = ( marginTop < 0 ? 0 : marginTop) +'px';\r
1557                         \r
1558                         styleLeft.top = marginTop +'px';\r
1559                         styleLeft.width = ( marginX < 0 ? 0 : marginX) +'px';\r
1560                         styleLeft.height = ( _h + marginBottom) +'px';\r
1561                         \r
1562                         styleRight.top = marginTop +'px';\r
1563                         styleRight.left = _w +marginX +'px';\r
1564                         styleRight.width = ( rightWidth < 0 ? 0 : rightWidth) +'px';\r
1565                         styleRight.height = ( _h + marginBottom) +'px';\r
1566                         \r
1567                         styleBottom.top = ( _h +marginTop) +'px';\r
1568                         styleBottom.left = marginX +'px';\r
1569                         styleBottom.width = _w +'px';\r
1570                         styleBottom.height = ( marginBottom < 0 ? 0 : marginBottom) +'px';\r
1571                 }\r
1572                 return {\r
1573                         onCanvasResize: resize\r
1574                 }\r
1575         })();\r
1576 \r
1577 \r
1578         var MIN_PANEL_HEIGHT = 20,\r
1579                 RESIZER_BORDER_WIDTH = 1;\r
1580 \r
1581 /*\r
1582  * PANEL_CONTROL\r
1583  */\r
1584         var PANEL_CONTROL = ( function(){\r
1585                 var DEFAULT_PANEL_WIDTH = 400,\r
1586                         DEFAULT_PANEL_HEIGHT = 300,\r
1587                         BORDER_WIDTH = 2,\r
1588                         canvasW, canvasH, canvasX, canvasY,\r
1589                         xOffset, yOffset, startCanvasX, startCanvasY,\r
1590                         isDragging = false,\r
1591                         isCanvasDraggble = false;                       \r
1592                 \r
1593                 var     panelElm, borderWidth;\r
1594                 \r
1595                 function resize( isResizerTopAction, _x, _y, _w, _h){\r
1596                         canvasX = _x !== undefined ? _x : canvasX;\r
1597                         canvasY = _y !== undefined ? _y : canvasY;\r
1598                         canvasW = _w !== undefined ? _w : canvasW;\r
1599                         canvasH = _h !== undefined ? _h : canvasH;\r
1600                         \r
1601                         panelElm.css( {\r
1602                                 left:   canvasX -BORDER_WIDTH,\r
1603                                 top:    canvasY -BORDER_WIDTH,\r
1604                                 width:  canvasW,\r
1605                                 height: canvasH\r
1606                         });\r
1607                         \r
1608                         PANEL_RESIZER_TOP.onCanvasResize( canvasX, canvasY, canvasW, canvasH);\r
1609                         PANEL_RESIZER_BOTTOM.onCanvasResize( canvasX, canvasY, canvasW, canvasH);\r
1610                         GRID_CONTROL.onCanvasResize( canvasX, canvasY);\r
1611                         WHITE_GLASS_CONTROL.onCanvasResize( canvasX, canvasY, canvasW, canvasH);\r
1612                         COMIC_ELEMENT_CONTROL.onCanvasResize( canvasX, canvasY, canvasW, canvasH, isResizerTopAction === true);\r
1613                 }\r
1614                 \r
1615                 function onSpaceUpdate(e){\r
1616                         if( e.type === 'keyup'){\r
1617                                 currentListener === null && updateMouseCursor( '');\r
1618                                 isCanvasDraggble = false;\r
1619                         } else {\r
1620                                 currentListener === null && updateMouseCursor( 'move');\r
1621                                 isCanvasDraggble = true;\r
1622                         }\r
1623                 }\r
1624                 \r
1625                 return {\r
1626                         init: function( _canvasW, _canvasH){\r
1627                                 panelElm = $( '#panel-border');\r
1628                                 borderWidth = panelElm.css( 'border-width');\r
1629 \r
1630                                 canvasW = _canvasW || DEFAULT_PANEL_WIDTH;\r
1631                                 canvasH = _canvasH || DEFAULT_PANEL_HEIGHT;\r
1632                                 canvasX = Math.floor( ( windowW -canvasW) /2);\r
1633                                 canvasY = Math.floor( ( windowH -canvasH) /2);\r
1634 \r
1635                                 pettanr.key.addKeyUpdateEvent( pettanr.view.EDITOR, 32, false, false, onSpaceUpdate);\r
1636 \r
1637                                 COMIC_ELEMENT_CONTROL.init( canvasX, canvasY, canvasW, canvasH);\r
1638                                 \r
1639                                 setTimeout( resize, 0);\r
1640                                 \r
1641                                 delete PANEL_CONTROL.init;\r
1642                         },\r
1643                         x: function(){\r
1644                                 return canvasX;\r
1645                         },\r
1646                         y: function(){\r
1647                                 return canvasY;\r
1648                         },\r
1649                         resize: resize,\r
1650                         onWindowResize: function( _windowW, _windowH){\r
1651                                 canvasX = Math.floor(( _windowW - canvasW) / 2);\r
1652                                 canvasY = Math.floor(( _windowH - canvasH) / 2);\r
1653                                 resize();\r
1654                         },\r
1655                         onMouseMove: function( _mouseX, _mouseY){\r
1656                                 if( isCanvasDraggble === true && isDragging === true){\r
1657                                         resize( false, startCanvasX +_mouseX -xOffset, startCanvasY +_mouseY -yOffset);\r
1658                                 }\r
1659                         },\r
1660                         onMouseUp: function( _mouseX, _mouseY){\r
1661                                 if( isCanvasDraggble === true){\r
1662                                         isDragging = false;\r
1663                                         updateMouseCursor( '');\r
1664                                 }\r
1665                         },\r
1666                         onMouseDown: function( _mouseX, _mouseY){\r
1667                                 if( isCanvasDraggble === true){\r
1668                                         xOffset = _mouseX;\r
1669                                         yOffset = _mouseY;\r
1670                                         startCanvasX = canvasX;\r
1671                                         startCanvasY = canvasY;\r
1672                                         isDragging = true;\r
1673                                         updateMouseCursor( 'move');\r
1674                                         return true;\r
1675                                 }\r
1676                         },\r
1677                         busy: function(){\r
1678                                 return isDragging === true;\r
1679                         }                               \r
1680                 }\r
1681         })();\r
1682 \r
1683 /*\r
1684  * --------------------------------------------------------------------------------------------\r
1685  * panel resizer\r
1686  */\r
1687         var PanelResizerClass = function( ID, isTop){\r
1688                 var ELM = document.getElementById( ID),\r
1689                         BORDER_WIDTH = 2,\r
1690                         RESIZER_HEIGHT = 30,\r
1691                         x = -BORDER_WIDTH /2,\r
1692                         y = isTop === true ? ( -5 -RESIZER_HEIGHT -BORDER_WIDTH) : 0,\r
1693                         w,\r
1694                         h = RESIZER_HEIGHT,\r
1695                         canvasX, canvasY, canvasW, canvasH,\r
1696                         yOffset, startY, startH,\r
1697                         isDragging = false,\r
1698                         MOUSE_CURSOR = updateMouseCursor;\r
1699                         \r
1700                 function restoreState( arg){\r
1701                         if( arg && arg.length > 3){\r
1702                                 PANEL_CONTROL.resize( isTop, arg[ 0] || canvasX, arg[ 1] || canvasY, arg[ 2] || canvasW, arg[ 3] || canvasH);\r
1703                         }\r
1704                 }\r
1705                         \r
1706                 return {\r
1707                         busy: function(){\r
1708                                 return isDragging;\r
1709                         },\r
1710                         onMouseDown: function( _mouseX, _mouseY){\r
1711                                 var _x = _mouseX -canvasX,\r
1712                                         _y = _mouseY -canvasY;\r
1713                                 if( _x < x || x + w < _x || _y < y || y + h < _y) return false;\r
1714                                 yOffset = _y;\r
1715                                 startY = canvasY;\r
1716                                 startH = canvasH;\r
1717                                 isDragging = true;\r
1718                                 MOUSE_CURSOR( 'n-resize');\r
1719                                 return true;\r
1720                         },\r
1721                         onMouseMove: function( _mouseX, _mouseY){\r
1722                                 var _x = _mouseX -canvasX,\r
1723                                         _y = _mouseY -canvasY;\r
1724                                 if( isDragging !== true){\r
1725                                         if( _x < x || x + w < _x || _y < y || y + h < _y) return false;\r
1726                                         COMIC_ELEMENT_OPERATOR.hide();\r
1727                                         MOUSE_CURSOR( 'pointer');\r
1728                                         return true;\r
1729                                 } else {\r
1730                                         var move = _y -yOffset;\r
1731                                         if( isTop === true){\r
1732                                                 if( canvasH - move < MIN_PANEL_HEIGHT){\r
1733                                                         move = canvasH -MIN_PANEL_HEIGHT;\r
1734                                                 }\r
1735                                                 PANEL_CONTROL.resize( true, canvasX, canvasY + move, canvasW, canvasH - move);\r
1736                                         } else {\r
1737                                                 var _h = startH +move;\r
1738                                                 if( 0 < _h && _h < windowH -canvasY -RESIZER_HEIGHT -5 -BORDER_WIDTH){\r
1739                                                         PANEL_CONTROL.resize( false, canvasX, canvasY, canvasW, _h < MIN_PANEL_HEIGHT ? MIN_PANEL_HEIGHT : _h);\r
1740                                                 }\r
1741                                         }\r
1742                                 }\r
1743                                 return true;\r
1744                         },\r
1745                         onMouseUp: function( _mouseX, _mouseY){\r
1746                                 if( isDragging !== true) return;\r
1747                                 ( startY !== canvasY || startH !== canvasH) && HISTORY.saveState( restoreState, [ NaN, startY, NaN, startH], [ NaN, canvasY, NaN, canvasH]);\r
1748                                 isDragging = false;\r
1749                                 MOUSE_CURSOR( '');\r
1750                         },\r
1751                         busy: function(){\r
1752                                 return isDragging\r
1753                         },\r
1754                         onCanvasResize: function( _x, _y, _w, _h){\r
1755                                 canvasX = _x;\r
1756                                 canvasY = _y;\r
1757                                 if( canvasW !== _w){\r
1758                                         ELM.style.width = ( _w +2) +'px';\r
1759                                         canvasW = _w;\r
1760                                 }\r
1761                                 canvasH = _h;\r
1762                                 y = isTop === true ? y : ( canvasH +5 +BORDER_WIDTH);\r
1763                                 w = canvasW +2;\r
1764                         }\r
1765                 }\r
1766         };\r
1767         var     PANEL_RESIZER_TOP = PanelResizerClass.apply( {}, [ 'panel-resizer-top', true]),\r
1768                 PANEL_RESIZER_BOTTOM = PanelResizerClass.apply( {}, [ 'panel-resizer-bottom', false]);\r
1769                 \r
1770         PanelResizerClass = undefined;\r
1771 /*\r
1772  *       - COMIC_ELEMENT_CONTROL\r
1773  *          - PanelResizerClass\r
1774  *          - COMIC_ELEMENT_OPERATOR\r
1775  *          - AbstractComicElement\r
1776  *          - ImageElementClass\r
1777  *          - TextElementClass\r
1778 */\r
1779 \r
1780         var MIN_OBJECT_SIZE = 19,\r
1781                 MOUSE_HIT_AREA = 10,\r
1782                 SAVE = HISTORY.saveState,\r
1783                 log,\r
1784                 DRAGGABLE_ELEMENT_ARRAY = [];// PANEL_RESIZER_TOP, PANEL_RESIZER_BOTTOM\r
1785         \r
1786 /*\r
1787  * --------------------------------------------------------------------------------------------\r
1788  * COMIC_ELEMENT_OPERATOR\r
1789  */\r
1790         var COMIC_ELEMENT_OPERATOR = ( function(){\r
1791                 var     MOUSE_CURSOR = updateMouseCursor,\r
1792                         SAVE = HISTORY.saveState,\r
1793                         INFOMATION = INFOMATION_WINDOW.update,\r
1794                         GRID_ENABLED = GRID_CONTROL.enabled,\r
1795                         HIT_AREA = MOUSE_HIT_AREA,\r
1796                         currentIsTextElement = false,\r
1797                         currentControler = null,\r
1798                         currentElement = null,\r
1799                         currentx, currenty, currentw, currenth, angle, flipV, flipH,\r
1800                         COMIC_ELEMENT_CONSOLE = ( function(){\r
1801                                 var LAYER_BACK_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'layer back', 'ctrl + B', layerBack, false, true, false),\r
1802                                         LAYER_FORWARD_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'layer forward', 'ctrl + F', layerForward, false, false, false),\r
1803                                         DELETE_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'delete', 'ctrl + D', del, false, true, true),\r
1804                                         EDIT_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'Edit Text', 'ctrl + E', edit, false, true, false),\r
1805                                         CHANGE_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'change', 'ctrl + U', change, false, false, true),\r
1806                                         jqStage,\r
1807                                         jqConsoleParent,\r
1808                                         jqConsoleWrapper,\r
1809                                         jqConsoleTail,\r
1810                                         jqImgConsole, jqTextConsole,\r
1811                                         currentElement = null,\r
1812                                         currentType = -1,\r
1813                                         visible = false,\r
1814                                         imgConsoleWidth, imgConsoleHeight,\r
1815                                         textConsoleWidth, textConsoleHeight,\r
1816                                         consoleWidth, consoleHeight,\r
1817                                         consoleX, consoleY,\r
1818                                         tailSize = 10,\r
1819                                         buttonClickable = false;\r
1820                                 \r
1821                                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 66, false, true, layerBack);\r
1822                                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 70, false, true, layerForward);\r
1823                                 \r
1824                                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 68, false, true, del);\r
1825                                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 69, false, true, edit);\r
1826                                 pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 85, false, true, change);\r
1827                                 \r
1828                                 function buttonBackOrForward( isBack){\r
1829                                         var     offest = jqConsoleWrapper.offset();\r
1830                                         jqConsoleWrapper.css( {\r
1831                                                 position:       isBack === true ? '' : 'absolute',\r
1832                                                 left:           isBack === true ? consoleX  : offest.left,\r
1833                                                 top:            isBack === true ? consoleY  : offest.top\r
1834                                         });\r
1835                                         buttonClickable === isBack && ( isBack === true ? jqConsoleParent : jqStage).append( jqConsoleWrapper);\r
1836                                         buttonClickable = !isBack;\r
1837                                 }\r
1838                                 function layerBack(){\r
1839                                         if( currentElement === null) return;\r
1840                                         COMIC_ELEMENT_CONTROL.replaceComicElement( currentElement, false);\r
1841                                         updateInfomation();\r
1842                                         SAVE( COMIC_ELEMENT_CONTROL.restoreReplaceObject, [ currentElement, true], [ currentElement, false]);\r
1843                                         var _z = currentElement.z;\r
1844                                         LAYER_BACK_BUTTON.visible( _z > 0);\r
1845                                         LAYER_FORWARD_BUTTON.visible( _z < DRAGGABLE_ELEMENT_ARRAY.length -1);\r
1846                                 }\r
1847                                 function layerForward(){\r
1848                                         if( currentElement === null) return;\r
1849                                         COMIC_ELEMENT_CONTROL.replaceComicElement( currentElement, true);\r
1850                                         updateInfomation();\r
1851                                         SAVE( COMIC_ELEMENT_CONTROL.restoreReplaceObject, [ currentElement, false], [ currentElement, true]);\r
1852                                         var _z = currentElement.z;\r
1853                                         LAYER_BACK_BUTTON.visible( _z > 0);\r
1854                                         LAYER_FORWARD_BUTTON.visible( _z < DRAGGABLE_ELEMENT_ARRAY.length -1);\r
1855                                 }\r
1856                                 function del(){\r
1857                                         if( currentElement === null) return;\r
1858                                         buttonBackOrForward( true);\r
1859                                         COMIC_ELEMENT_CONTROL.removeComicElement( currentElement);\r
1860                                         SAVE( COMIC_ELEMENT_CONTROL.restoreComicElement, [ true, currentElement], [ false, currentElement], true);\r
1861                                         COMIC_ELEMENT_OPERATOR.hide();\r
1862                                 }\r
1863                                 function edit(){\r
1864                                         if( currentElement === null || currentElement.type !== COMIC_ELEMENT_TYPE_TEXT) return;\r
1865                                         TEXT_EDITOR_CONTROL.show( currentElement);\r
1866                                         buttonBackOrForward( true);\r
1867                                 }\r
1868                                 function change(){\r
1869                                         if( currentElement === null) return;\r
1870                                         buttonBackOrForward( true);\r
1871                                         IMAGE_GROUP_EXPROLER.show( currentElement.url);\r
1872                                 }\r
1873                                 return {\r
1874                                         init: function(){\r
1875                                                 jqStage = jqEditor;\r
1876                                                 jqConsoleTail = $( '#comic-element-consol-tail');\r
1877                                                 jqImgConsole = $( '#image-element-consol').hide();\r
1878                                                 var imgConsoleSize = pettanr.util.getElementSize( jqImgConsole.get( 0));\r
1879                                                 imgConsoleWidth = imgConsoleSize.width;\r
1880                                                 imgConsoleHeight = imgConsoleSize.height;\r
1881                                                 \r
1882                                                 jqTextConsole = $( '#text-element-consol').hide();\r
1883                                                 var textConsoleSize = pettanr.util.getElementSize( jqTextConsole.get( 0));\r
1884                                                 textConsoleWidth = textConsoleSize.width;\r
1885                                                 textConsoleHeight = textConsoleSize.height;\r
1886                                                 \r
1887                                                 jqConsoleWrapper = $( '#comic-element-consol-wrapper').hide();\r
1888                                                 jqConsoleParent = jqConsoleWrapper.parent();\r
1889                                                 \r
1890                                                 $( '#edit-text-button').click( edit);\r
1891                                                 $( '#delete-image-button, #delete-text-button').click( del);\r
1892                                                 $( '#change-image-button').click( change);\r
1893                                                 $( '#layer-forward-button, #forward-text-button').click( layerForward);\r
1894                                                 $( '#layer-back-button, #back-text-button').click( layerBack);\r
1895                                                                                                         \r
1896                                                 delete COMIC_ELEMENT_CONSOLE.init;\r
1897                                         },\r
1898                                         show: function( _currentElement, _w, _h){\r
1899                                                 visible === false && jqConsoleWrapper.show();\r
1900                                                 visible = true;\r
1901                                                 currentElement = _currentElement;\r
1902                                                 var _currentType = _currentElement.type,\r
1903                                                         _z = _currentElement.z;\r
1904                                                 if( currentType !== _currentType){\r
1905                                                         currentType = _currentType;\r
1906                                                         jqImgConsole.toggle( _currentType === COMIC_ELEMENT_TYPE_IMAGE);\r
1907                                                         jqTextConsole.toggle( _currentType === COMIC_ELEMENT_TYPE_TEXT);\r
1908                                                         consoleWidth = _currentType === COMIC_ELEMENT_TYPE_IMAGE ? imgConsoleWidth : textConsoleWidth;\r
1909                                                         consoleHeight = _currentType === COMIC_ELEMENT_TYPE_IMAGE ? imgConsoleHeight : textConsoleHeight;\r
1910                                                 }\r
1911                                                 consoleX = Math.floor( ( _w -consoleWidth) /2);\r
1912                                                 \r
1913                                                 LAYER_BACK_BUTTON.visible( _z > 0);\r
1914                                                 LAYER_FORWARD_BUTTON.visible( _z < DRAGGABLE_ELEMENT_ARRAY.length -1);\r
1915                                                 DELETE_BUTTON.visible( true);\r
1916                                                 EDIT_BUTTON.visible( _currentType === COMIC_ELEMENT_TYPE_TEXT);\r
1917                                                 CHANGE_BUTTON.visible( false);\r
1918                                                 \r
1919                                                 if( _w > consoleWidth * 1.5 && _h > consoleHeight * 1.5){\r
1920                                                         consoleY = Math.floor( ( _h -consoleHeight) /2);\r
1921                                                         jqConsoleWrapper.css( {\r
1922                                                                 left:                   consoleX,\r
1923                                                                 top:                    consoleY\r
1924                                                         }).removeClass( 'console-out');\r
1925                                                 } else {\r
1926                                                         consoleY = _h +tailSize;\r
1927                                                         jqConsoleWrapper.css( {\r
1928                                                                 left:                   consoleX,\r
1929                                                                 top:                    consoleY\r
1930                                                         }).addClass( 'console-out');\r
1931                                                 }\r
1932                                         },\r
1933                                         hide: function (){\r
1934                                                 visible === true && jqConsoleWrapper.hide();\r
1935                                                 visible = false;\r
1936                                                 currentElement = null;\r
1937                                                 LAYER_BACK_BUTTON.visible( false);\r
1938                                                 LAYER_FORWARD_BUTTON.visible( false);\r
1939                                                 DELETE_BUTTON.visible( false);\r
1940                                                 EDIT_BUTTON.visible( false);\r
1941                                                 CHANGE_BUTTON.visible( false);\r
1942                                         },\r
1943                                         x: function(){ return consoleX;},\r
1944                                         y: function(){ return consoleY;},\r
1945                                         w: function(){ return consoleWidth;},\r
1946                                         h: function(){ return consoleHeight;},\r
1947                                         onMouseMove: function( _mouseX, _mouseY){\r
1948                                                 if( consoleX > _mouseX || consoleY > _mouseY || consoleX +consoleWidth < _mouseX || consoleY +consoleHeight < _mouseY){\r
1949                                                         buttonClickable === true && buttonBackOrForward( true);\r
1950                                                         return false;\r
1951                                                 }\r
1952                                                 buttonClickable === false && buttonBackOrForward( false);\r
1953                                                 return true;\r
1954                                         },\r
1955                                         onMouseOut: function( _mouseX, _mouseY){\r
1956                                                 buttonClickable === true && buttonBackOrForward( true);\r
1957                                         }\r
1958                                 }\r
1959                         })(),\r
1960                         TAIL_CONTROLER = ( function(){\r
1961                                 var     ELM_MOVER = document.getElementById( 'balloon-tail-mover'),\r
1962                                         SIZE = pettanr.util.getElementSize( ELM_MOVER).width,\r
1963                                         SIN = Math.sin,\r
1964                                         COS = Math.cos,\r
1965                                         ATAN = Math.atan,\r
1966                                         FLOOR = Math.floor,\r
1967                                         DEG_TO_RAD = Math.PI / 180,\r
1968                                         RAD_TO_DEG = 1 /DEG_TO_RAD,\r
1969                                         currentText = null,\r
1970                                         tailX, tailY,\r
1971                                         balloonW, balloonH, balloonA, radA,\r
1972                                         visible = false,\r
1973                                         startA;\r
1974                                 \r
1975                                 function draw( _w, _h, _a){\r
1976                                         balloonW = _w !== undefined ? _w : balloonW;\r
1977                                         balloonH = _h !== undefined ? _h : balloonH;\r
1978                                         balloonA = _a !== undefined ? _a : balloonA;\r
1979                                         radA = balloonA *DEG_TO_RAD;\r
1980                                         tailX = FLOOR( ( ( COS( radA) /2 +0.5) *( balloonW +SIZE)) -SIZE /2);\r
1981                                         tailY = FLOOR( ( ( SIN( radA) /2 +0.5) *( balloonH +SIZE)) -SIZE /2);\r
1982                                         ELM_MOVER.style.left = tailX +'px';\r
1983                                         ELM_MOVER.style.top = tailY +'px';\r
1984                                         log.html( [ balloonW, balloonH, balloonA].join());\r
1985                                 }\r
1986                                 function hitTest( _mouseX, _mouseY){\r
1987                                         var _x = tailX -SIZE /2,\r
1988                                                 _y = tailY -SIZE /2;\r
1989                                                 ret = currentIsTextElement === true && _x <= _mouseX && _y <= _mouseY && _x +SIZE >= _mouseX && _y +SIZE >= _mouseY;\r
1990                                         ret === true && MOUSE_CURSOR( 'move');\r
1991                                         return ret;\r
1992                                 }\r
1993                                 return {\r
1994                                         update: draw,\r
1995                                         show: function( _currentText){\r
1996                                                 /*\r
1997                                                  * visibilityのほうがいい, display:none だと ie で描画が狂う\r
1998                                                  */\r
1999                                                 ELM_MOVER.style.visibility = '';\r
2000                                                 draw( _currentText.w, _currentText.h, _currentText.angle());\r
2001                                                 currentText = _currentText;\r
2002                                         },\r
2003                                         hitTest: hitTest,\r
2004                                         hide: function(){\r
2005                                                 ELM_MOVER.style.visibility = 'hidden';\r
2006                                                 currentText = null;\r
2007                                         },\r
2008                                         onStart: function( _currentText, _mouseX, _mouseY){\r
2009                                                 if( hitTest( _mouseX -currentx, _mouseY -currenty) === true){\r
2010                                                         currentText = _currentText;\r
2011                                                         startA = _currentText.angle();\r
2012                                                         return true;\r
2013                                                 }\r
2014                                                 currentText = null;\r
2015                                                 return false;\r
2016                                         },\r
2017                                         onDrag: function( _mouseX, _mouseY){\r
2018                                                 _mouseX = _mouseX -currentText.x -currentw /2;\r
2019                                                 _mouseY = _mouseY -currentText.y -currenth /2; //Balloonの中心を0,0とする座標系に変換\r
2020                                                 \r
2021                                                 draw( currentw, currenth,\r
2022                                                         _mouseX !== 0 ?\r
2023                                                                 ATAN( _mouseY /_mouseX) *RAD_TO_DEG +( _mouseX < 0 ? 180 : 0) :\r
2024                                                                 _mouseY > 0 ? 90 : -90\r
2025                                                 );\r
2026                                                 currentText && currentText.angle( balloonA);\r
2027                                                 updateInfomation( undefined, undefined, undefined, balloonA);\r
2028                                         },\r
2029                                         onFinish: function(){\r
2030                                                 startA !== currentText.angle() && saveComicElementStatus( currentx, currenty, currentw, currenth, startA);\r
2031                                                 startA !== currentText.angle() && resize( undefined, undefined, undefined, undefined, currentText.angle());\r
2032                                                 currentText = null;\r
2033                                         },\r
2034                                         onCancel: function(){\r
2035                                                 resize( undefined, undefined, undefined, undefined, startA);\r
2036                                         }\r
2037                                 }\r
2038                         })(),\r
2039                         RESIZE_CONTROLER = ( function(){\r
2040                                 var POSITION_ARRAY = [],\r
2041                                         FLOOR = Math.floor,\r
2042                                         CURSOR_AND_FLIP = [\r
2043                                                 { cursor:       'n-resize',             v: 3},\r
2044                                                 { cursor:       'e-resize',             h: 2},\r
2045                                                 { cursor:       'e-resize',             h: 1},\r
2046                                                 { cursor:       'n-resize',             v: 0},\r
2047                                                 { cursor:       'nw-resize',    h: 5, v: 6, vh: 7},\r
2048                                                 { cursor:       'ne-resize',    h: 4, v: 7, vh: 6},\r
2049                                                 { cursor:       'ne-resize',    h: 7, v: 4, vh: 5},\r
2050                                                 { cursor:       'nw-resize',    h: 6, v: 5, vh: 4}\r
2051                                         ],      \r
2052                                         elmResizerContainerStyle = document.getElementById( 'comic-element-resizer-container').style,\r
2053                                         elmResizerTopStyle = document.getElementById( 'comic-element-resizer-top').style,\r
2054                                         elmResizerLeftStyle = document.getElementById( 'comic-element-resizer-left').style,\r
2055                                         elmResizerRightStyle = document.getElementById( 'comic-element-resizer-right').style,\r
2056                                         elmResizerBottomStyle = document.getElementById( 'comic-element-resizer-bottom').style,\r
2057                                         x, y, w, h,\r
2058                                         currentIndex = -1,\r
2059                                         currentElement,\r
2060                                         currentIsTextElement = false;\r
2061                                 \r
2062                                 elmResizerContainerStyle.display = 'none';\r
2063                                 \r
2064                                 var RESIZE_WORK_ARRAY = [\r
2065                                                 { x:    0, w:    0, y:  1, h:   -1}, //top\r
2066                                                 { x:    1, w:   -1, y:  0, h:    0}, //left\r
2067                                                 { x:    0, w:    1, y:  0, h:    0}, //right\r
2068                                                 { x:    0, w:    0, y:  0, h:    1}, //bottom\r
2069                                                 { x:    1, w:   -1, y:  1, h:   -1}, //top-left\r
2070                                                 { x:    0, w:    1, y:  1, h:   -1}, //top-right\r
2071                                                 { x:    1, w:   -1, y:  0, h:    1}, //bottom-left\r
2072                                                 { x:    0, w:    1, y:  0, h:    1}  //bottom-right\r
2073                                         ],\r
2074                                         startX, startY, startW, startH, startFilpV, startFilpH, startAspect,\r
2075                                         baseX, baseY, baseW, baseH,\r
2076                                         currentX, currentY, currentW, currentH,\r
2077                                         resultX, resultY, resultW, resultH,\r
2078                                         xOffset, yOffset,\r
2079                                         error = 0;\r
2080                                 \r
2081                                 function draw( _x, _y, _w, _h){\r
2082                                         x = _x !== undefined ? _x : x;\r
2083                                         y = _y !== undefined ? _y : y;\r
2084                                         w = _w !== undefined ? _w : w;\r
2085                                         h = _h !== undefined ? _h : h;\r
2086                                         elmResizerContainerStyle.left = x +'px';\r
2087                                         elmResizerContainerStyle.top = y +'px';\r
2088                                         elmResizerContainerStyle.width = w +'px';\r
2089                                         elmResizerContainerStyle.height = h +'px';\r
2090                                         elmResizerTopStyle.left = FLOOR( w /2 -10 /2) +'px';\r
2091                                         elmResizerLeftStyle.top = FLOOR( h /2 -10 /2) +'px';\r
2092                                         elmResizerRightStyle.top = FLOOR( h /2 -10 /2) +'px';\r
2093                                         elmResizerBottomStyle.left = FLOOR( w /2 -10 /2) +'px';\r
2094                                         \r
2095                                         POSITION_ARRAY.splice( 0, POSITION_ARRAY.length);\r
2096                                         POSITION_ARRAY.push(\r
2097                                                 {x:     x +5,                                   y:      y -HIT_AREA,            w:      w -5 *2,                h:      HIT_AREA +5},\r
2098                                                 {x: x -HIT_AREA,                        y:      y +HIT_AREA +5,         w:      HIT_AREA +5,    h:      h -5 *2},\r
2099                                                 {x: x +w -5,                            y:      y +HIT_AREA +5,         w:      HIT_AREA +5,    h:      h -5 *2},\r
2100                                                 {x:     x +5,                                   y:      y +h -5,                        w:      w -5 *2,                h:      HIT_AREA +5},\r
2101                                                 {x:     x -HIT_AREA,                    y:      y -HIT_AREA,            w:      HIT_AREA +5,    h:      HIT_AREA +5},\r
2102                                                 {x: x +w -HIT_AREA,                     y:      y -HIT_AREA,            w:      HIT_AREA +5,    h:      HIT_AREA +5},\r
2103                                                 {x:     x -HIT_AREA,                    y:      y +h -5,                        w:      HIT_AREA +5,    h:      HIT_AREA +5},\r
2104                                                 {x:     x +w -5,                                y:      y +h -5,                        w:      HIT_AREA +5,    h:      HIT_AREA +5}\r
2105                                         );\r
2106                                 }\r
2107                                 \r
2108                                 function update( _x, _y, _w, _h){\r
2109                                         resultX = _x !== undefined ? _x : currentX;\r
2110                                         resultY = _y !== undefined ? _y : currentY;\r
2111                                         resultW = _w !== undefined ? _w : currentW;\r
2112                                         resultH = _h !== undefined ? _h : currentH;\r
2113                                         \r
2114                                         if( currentIsTextElement === false && currentIndex > 3 && pettanr.key.shiftEnabled() === true){\r
2115                                                 if( startAspect >= 1){\r
2116                                                         _w = resultW;\r
2117                                                         resultW = Math.floor( startAspect * resultH);\r
2118                                                         resultX = resultX +( currentIndex % 2 === 0 ? _w -resultW : 0);\r
2119                                                 } else {\r
2120                                                         _h = resultH;\r
2121                                                         resultH = Math.floor( resultW / startAspect);\r
2122                                                         resultY = resultY + ( currentIndex <= 5 ? _h -resultH : 0);\r
2123                                                 }\r
2124                                         }\r
2125                                         draw( resultX, resultY, resultW, resultH);\r
2126                                         currentElement.resize( resultX, resultY, resultW, resultH);\r
2127                                         currentIsTextElement === true && TAIL_CONTROLER.update( resultW, resultH);\r
2128                                         COMIC_ELEMENT_CONSOLE.show( currentElement, resultW, resultH);\r
2129                                         updateInfomation( resultX, resultY, undefined, undefined, resultW, resultH);\r
2130                                 }\r
2131                                 function getIndex( _mouseX, _mouseY){\r
2132                                         var     p,\r
2133                                                 l = POSITION_ARRAY.length;\r
2134                                         for( var i=0; i<l; i++){\r
2135                                                 p = POSITION_ARRAY[ i];\r
2136                                                 if( p.x <= _mouseX && p.y <= _mouseY && p.x + p.w >= _mouseX && p.y +p.h >= _mouseY){\r
2137                                                         MOUSE_CURSOR( CURSOR_AND_FLIP[ i].cursor);\r
2138                                                         return currentIndex = i;\r
2139                                                 }\r
2140                                         }\r
2141                                         return -1;\r
2142                                 }\r
2143                                 function flip( _flipV, _flipH){\r
2144                                         var p = CURSOR_AND_FLIP[ currentIndex];\r
2145                                         currentIndex = _flipH === true || _flipV === true ? p[\r
2146                                                         _flipH === true && _flipV === true ? 'vh' : ( _flipH === true ? 'h' : 'v')\r
2147                                                 ] : currentIndex;\r
2148                                         MOUSE_CURSOR( CURSOR_AND_FLIP[ currentIndex].cursor);\r
2149                                         currentElement.flip( _flipV, _flipH);\r
2150                                 }\r
2151                                 return {\r
2152                                         x: function(){ return x;},\r
2153                                         y: function(){ return y;},\r
2154                                         w: function(){ return w;},\r
2155                                         h: function(){ return h;},\r
2156                                         update: draw,\r
2157                                         index: getIndex,\r
2158                                         show: function( _currentElement){\r
2159                                                 currentElement = _currentElement;\r
2160                                                 currentIsTextElement = _currentElement.type === COMIC_ELEMENT_TYPE_TEXT;\r
2161                                                 elmResizerContainerStyle.display = '';\r
2162                                         },\r
2163                                         hide: function(){\r
2164                                                 currentElement = null;\r
2165                                                 elmResizerContainerStyle.display = 'none';\r
2166                                         },\r
2167                                         onStart: function( _currentElement, _mouseX, _mouseY){\r
2168                                                 currentElement = _currentElement;\r
2169                                                 currentIsTextElement = _currentElement.type === COMIC_ELEMENT_TYPE_TEXT;\r
2170                                                 if( _currentElement.keepSize === true) return false;\r
2171                                                 currentIndex = getIndex( _mouseX, _mouseY);\r
2172                                                 if( currentIndex === -1) return false;\r
2173                                                 xOffset = _mouseX;\r
2174                                                 yOffset = _mouseY;\r
2175                                                 startX = baseX = x = _currentElement.x;\r
2176                                                 startY = baseY = y = _currentElement.y;\r
2177                                                 startW = baseW = w = _currentElement.w;\r
2178                                                 startH = baseH = h = _currentElement.h;\r
2179                                                 startFilpV = flipV;\r
2180                                                 startFilpH = flipH;\r
2181                                                 startAspect = startW /startH;\r
2182                                                 return true;\r
2183                                         },\r
2184                                         onDrag: function( _mouseX, _mouseY){\r
2185                                                 var com = RESIZE_WORK_ARRAY[ currentIndex],\r
2186                                                         moveX = _mouseX -xOffset,\r
2187                                                         moveY = _mouseY -yOffset,\r
2188                                                         _x = baseX +moveX *com.x,\r
2189                                                         _y = baseY +moveY *com.y,\r
2190                                                         _w = baseW +moveX *com.w,\r
2191                                                         _h = baseH +moveY *com.h,\r
2192                                                         _updated = moveX !== 0 || moveY !== 0;\r
2193                                                 \r
2194                                                 // opera がときどき baseH の値を忘れる ??\r
2195                                                 if( _x === undefined || _y === undefined || _w === undefined || _h === undefined){\r
2196                                                         ++error;\r
2197                                                         return;\r
2198                                                 }\r
2199                                                 \r
2200                                                 if( _w >= MIN_OBJECT_SIZE && _h >= MIN_OBJECT_SIZE){\r
2201                                                         \r
2202                                                 } else \r
2203                                                 if( _w >= -MIN_OBJECT_SIZE && _h >= -MIN_OBJECT_SIZE){\r
2204                                                         return;\r
2205                                                 } else \r
2206                                                 if( currentElement.type === COMIC_ELEMENT_TYPE_TEXT){\r
2207                                                         return;\r
2208                                                 } else \r
2209                                                 if( _w < -MIN_OBJECT_SIZE || _h < -MIN_OBJECT_SIZE){\r
2210                                                         var __x = 0,\r
2211                                                                 __y = 0;\r
2212                                                         if( _w < -MIN_OBJECT_SIZE && _h > MIN_OBJECT_SIZE){\r
2213                                                         // flipH\r
2214                                                                 __x = _x;\r
2215                                                                 baseX = _x = _x +_w;\r
2216                                                                 baseY = _y;\r
2217                                                                 baseW = _w = __x -_x;\r
2218                                                                 baseH = _h;\r
2219                                                                 flip( false, true);\r
2220                                                                 flipV = currentElement.flipV();\r
2221                                                         } else \r
2222                                                         if( _w > MIN_OBJECT_SIZE && _h < -MIN_OBJECT_SIZE){\r
2223                                                         // flipV\r
2224                                                                 __y = _y;\r
2225                                                                 baseX = _x;\r
2226                                                                 baseY = _y = _y +_h;\r
2227                                                                 baseW = _w;\r
2228                                                                 baseH = _h = __y -_y;\r
2229                                                                 flip( true, false);\r
2230                                                                 flipH = currentElement.flipH();\r
2231                                                         } else {\r
2232                                                         // flipVH\r
2233                                                                 __x = _x;\r
2234                                                                 __y = _y;\r
2235                                                                 baseX = _x = _x +_w;\r
2236                                                                 baseY = _y = _y +_h;\r
2237                                                                 baseW = _w = __x -_x;\r
2238                                                                 baseH = _h = __y -_y;\r
2239                                                                 flip( true, true);\r
2240                                                                 flipV = currentElement.flipV();\r
2241                                                                 flipH = currentElement.flipH();\r
2242                                                         }\r
2243                                                         _updated = true;\r
2244                                                         xOffset = _mouseX;\r
2245                                                         yOffset = _mouseY;      \r
2246                                                 }\r
2247                                                 currentX = _x;\r
2248                                                 currentY = _y;\r
2249                                                 currentW = _w;\r
2250                                                 currentH = _h;\r
2251                                                 _updated === true && update( _x, _y, _w, _h);\r
2252                                                 \r
2253                                                 log.html( [\r
2254                                                                 'currentIndex:', currentIndex, \r
2255                                                                 'baseW', baseW, 'baseH', baseH,'<br>',\r
2256                                                                 'mouse', _mouseX, _mouseY,'<br>',\r
2257                                                                 'move', moveX, moveY,'<br>',\r
2258                                                                 'xy', _x, _y, 'wh',_w, _h,'<br>',\r
2259                                                                 'com.w', com.w, 'com.h', com.h,'<br>',\r
2260                                                                 'current',currentW, currentH,'<br>',\r
2261                                                                 'result', resultY, resultH,\r
2262                                                                 'err', error\r
2263                                                 ].join( ' , '));\r
2264                                         },\r
2265                                         onFinish: function(){\r
2266                                                 MOUSE_CURSOR( '');\r
2267                                                 if( resultW === startW && resultH === startH && resultX === startX && resultY === startY) return;\r
2268                                                 resize( resultX, resultY, resultW, resultH);\r
2269                                                 currentElement.resize( resultX, resultY, resultW, resultH);\r
2270                                                 saveComicElementStatus( startX, startY, startW, startH, angle, startFilpV, startFilpH);\r
2271                                         },\r
2272                                         onCancel: function(){\r
2273                                                 MOUSE_CURSOR( '');\r
2274                                                 resize( startX, startY, startW, startH);\r
2275                                                 currentElement.type === COMIC_ELEMENT_TYPE_IMAGE ?\r
2276                                                         currentElement.animate( startX, startY, startW, startH, startFilpV, startFilpH) :\r
2277                                                         currentElement.animate( startX, startY, startW, startH, angle);\r
2278                                         },\r
2279                                         onShiftUpdate: update,\r
2280                                         onCtrlUpdate: update\r
2281                                 }\r
2282                         })(),\r
2283                         POSITION_CONTROLER = ( function(){\r
2284                                 var currentElement,\r
2285                                         startX, startY,\r
2286                                         x, currentY,\r
2287                                         xOffset, yOffset,\r
2288                                         isCopy = false;\r
2289                                 \r
2290                                 function update( _x, _y){\r
2291                                         x = _x !== undefined ? _x : x;\r
2292                                         y = _y !== undefined ? _y : y;\r
2293                                         RESIZE_CONTROLER.update( x, y);\r
2294                                         currentElement.resize( x, y);\r
2295                                         updateInfomation( x, y);                                                        \r
2296                                 }\r
2297                                 \r
2298                                 return {\r
2299                                         onStart: function( _currentElement, _mouseX, _mouseY){\r
2300                                                 currentElement = _currentElement;\r
2301                                                 xOffset = _mouseX;\r
2302                                                 yOffset = _mouseY;\r
2303                                                 startX = x = currentx;\r
2304                                                 startY = y = currenty;\r
2305                                                 MOUSE_CURSOR( 'move');\r
2306                                         },\r
2307                                         onDrag: function( _mouseX, _mouseY){\r
2308                                                 var moveX = _mouseX -xOffset,\r
2309                                                         moveY = _mouseY -yOffset,\r
2310                                                         _x = currentx +moveX,\r
2311                                                         _y = currenty +moveY;\r
2312                                                 if( GRID_ENABLED() === true){\r
2313                                                         _x = Math.floor( _x / 10) * 10;\r
2314                                                         _y = Math.floor( _y / 10) * 10;\r
2315                                                 }\r
2316                                                 update( _x, _y);\r
2317                                         },\r
2318                                         onFinish: function(){\r
2319                                                 MOUSE_CURSOR( '');\r
2320                                                 if( x === startX && y === startY) return;\r
2321                                                 resize( x, y);\r
2322                                                 currentElement.resize( x, y);\r
2323                                                 saveComicElementStatus( startX, startY);\r
2324                                         },\r
2325                                         onCancel: function(){\r
2326                                                 MOUSE_CURSOR( '');\r
2327                                                 resize( startX, startY);\r
2328                                                 currentElement.animate( startX, startY);\r
2329                                         },\r
2330                                         onShiftUpdate: update,\r
2331                                         onCtrlUpdate: update\r
2332                                 }\r
2333                         })();\r
2334 \r
2335                         function resize( _x, _y, _w, _h, _angle){\r
2336                                 currentx = _x !== undefined ? _x : currentx;\r
2337                                 currenty = _y !== undefined ? _y : currenty;\r
2338                                 currentw = _w !== undefined ? _w : currentw;\r
2339                                 currenth = _h !== undefined ? _h : currenth;\r
2340                                 angle = _angle !== undefined ? _angle : angle;\r
2341 \r
2342                                 RESIZE_CONTROLER.update( currentx, currenty, currentw, currenth);\r
2343                                 currentIsTextElement === true && TAIL_CONTROLER.update( currentw, currenth, angle);\r
2344                                 COMIC_ELEMENT_CONSOLE.show( currentElement, currentw, currenth);\r
2345                                 updateInfomation( currentx, currenty, currentElement.z, angle, currentw, currenth);\r
2346                         }\r
2347                         function updateInfomation( _x, _y, _z, _a, _w, _h, keepAspect){\r
2348                                 _w = _w !== undefined ? _w : currentw;\r
2349                                 _h = _h !== undefined ? _h : currenth;\r
2350                                 INFOMATION(\r
2351                                         currentElement === null ? -1 : currentElement.type,\r
2352                                         _x !== undefined ? _x : currentx,\r
2353                                         _y !== undefined ? _y : currenty,\r
2354                                         _z !== undefined ? _z : ( currentElement === null ? '*' : currentElement.z),\r
2355                                         _a !== undefined ? Math.floor( _a) : ( currentIsTextElement === true ? Math.floor( angle) : '-'),\r
2356                                         _w,\r
2357                                         _h,\r
2358                                         currentElement === null || currentIsTextElement === true ? '-' : ( currentElement.actualW() === 0 ? '?' : Math.floor( _w / currentElement.actualW() *100)),\r
2359                                         currentElement === null || currentIsTextElement === true ? '-' : ( currentElement.actualH() === 0 ? '?' : Math.floor( _h / currentElement.actualH() *100)),\r
2360                                         currentElement === null || currentIsTextElement === true ? '-' : currentElement.keepAspect\r
2361                                 );\r
2362                         }\r
2363                         function show( _currentElement){\r
2364                                 currentElement === null && RESIZE_CONTROLER.show( _currentElement);\r
2365                                 if( currentElement !== _currentElement){\r
2366                                         currentElement = _currentElement;\r
2367                                         \r
2368                                         currentIsTextElement = ( _currentElement.type === COMIC_ELEMENT_TYPE_TEXT);\r
2369                                         currentIsTextElement === true ? TAIL_CONTROLER.show( _currentElement) : TAIL_CONTROLER.hide();\r
2370                                         \r
2371                                         flipV = currentIsTextElement === false ? _currentElement.flipV() : 0;\r
2372                                         flipH = currentIsTextElement === false ? _currentElement.flipH() : 0;\r
2373                                         \r
2374                                         resize(\r
2375                                                 _currentElement.x, _currentElement.y, _currentElement.w, _currentElement.h,\r
2376                                                 currentIsTextElement === true ? _currentElement.angle() : 0\r
2377                                         );\r
2378                                 }\r
2379                         }\r
2380                         function hide(){\r
2381                                 currentElement !== null && RESIZE_CONTROLER.hide();\r
2382                                 currentElement = null;\r
2383                                 MOUSE_CURSOR( '');\r
2384                                 TAIL_CONTROLER.hide();\r
2385                                 COMIC_ELEMENT_CONSOLE.hide();\r
2386                                 updateInfomation();\r
2387                         }\r
2388                         function restoreState( arg){\r
2389                                 if( arg && arg.length !== 8) return;\r
2390                                 var _currentElement = arg[ 0],\r
2391                                         _x = arg[ 1], _y = arg[ 2], _w = arg[ 3], _h = arg[ 4],\r
2392                                         _a = arg[ 5],\r
2393                                         _flipV = arg[ 6], _flipH = arg[ 7];\r
2394                                 if( !_currentElement && !currentControler) return;\r
2395                                 _currentElement.type === COMIC_ELEMENT_TYPE_IMAGE ?\r
2396                                         _currentElement.animate( _x, _y, _w, _h, _flipV, _flipH) :\r
2397                                         _currentElement.animate( _x, _y, _w, _h, _a);\r
2398                                 currentControler !== null && currentControler.onCancel && currentControler.onCancel();\r
2399                                 currentControler = null;\r
2400                                 currentElement === _currentElement ? resize( _x, _y, _w, _h, _a) : show( _currentElement);\r
2401                         }\r
2402                         function saveComicElementStatus( startX, startY, startW, startH, startA, startFilpV, startFilpH){\r
2403                                 startX = startX !== undefined ? startX : currentx;\r
2404                                 startY = startY !== undefined ? startY : currenty;\r
2405                                 startW = startW !== undefined ? startW : currentw;\r
2406                                 startH = startH !== undefined ? startH : currenth;\r
2407                                 startA = startA !== undefined ? startA : angle;\r
2408                                 startFilpV = startFilpV !== undefined ? startFilpV : flipV;\r
2409                                 startFilpH = startFilpH !== undefined ? startFilpH : flipH;\r
2410                                 currentElement && SAVE( restoreState,\r
2411                                         [ currentElement, startX, startY, startW, startH, startA, startFilpV, startFilpH],\r
2412                                         [ currentElement, currentx, currenty, currentw, currenth, angle, flipV, flipH]\r
2413                                 );\r
2414                         }\r
2415                         pettanr.key.addKeyUpdateEvent( pettanr.view.EDITOR, 16, undefined, undefined, function( e){\r
2416                                 currentControler !== null && currentControler.onShiftUpdate && currentControler.onShiftUpdate();\r
2417                         });\r
2418                         pettanr.key.addKeyUpdateEvent( pettanr.view.EDITOR, 17, undefined, undefined, function(){\r
2419                                 currentControler !== null && currentControler.onCtrlUpdate && currentControler.onCtrlUpdate();\r
2420                         });\r
2421                         pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 27, false, false, function(){\r
2422                                 currentControler !== null && currentControler.onCancel && currentControler.onCancel();\r
2423                                 currentControler = null;\r
2424                         });\r
2425                 return {\r
2426                         init: function(){\r
2427                                 COMIC_ELEMENT_CONSOLE.init();\r
2428                                 hide();\r
2429                                 delete COMIC_ELEMENT_OPERATOR.init;\r
2430                         },\r
2431                         hide: hide,\r
2432                         busy: function(){\r
2433                                 return currentControler !== null;\r
2434                         },\r
2435                         hitareaX: function( _comicElement, _x){\r
2436                                 if( _comicElement === currentElement){\r
2437                                         var _consoleX = COMIC_ELEMENT_CONSOLE.x();\r
2438                                         return currentx +( _consoleX < 0 ? _consoleX : 0) -HIT_AREA;\r
2439                                 }\r
2440                                 return _x -HIT_AREA;\r
2441                         },\r
2442                         hitareaY: function( _comicElement, _y){\r
2443                                 return _y -HIT_AREA;\r
2444                         },\r
2445                         hitareaW: function( _comicElement, _w){\r
2446                                 if( _comicElement === currentElement){\r
2447                                         var _consoleW = COMIC_ELEMENT_CONSOLE.w();\r
2448                                         return ( _consoleW < currentw ? currentw : _consoleW) +HIT_AREA *2;\r
2449                                 }\r
2450                                 return _w +HIT_AREA *2;\r
2451                         },\r
2452                         hitareaH: function( _comicElement, _h){\r
2453                                 if( _comicElement === currentElement){\r
2454                                         var _consoleY = COMIC_ELEMENT_CONSOLE.y();\r
2455                                         return ( _consoleY < currenth ? currenth : _consoleY +COMIC_ELEMENT_CONSOLE.h()) +HIT_AREA *2;\r
2456                                 }\r
2457                                 return _h +HIT_AREA *2;\r
2458                         },\r
2459                         onMouseDown: function( _currentElement, _mouseX, _mouseY){\r
2460                                 //show( _currentElement);\r
2461                                 if( currentIsTextElement === true && TAIL_CONTROLER.onStart( _currentElement, _mouseX, _mouseY) === true){\r
2462                                         currentControler = TAIL_CONTROLER;\r
2463                                 } else\r
2464                                 if( RESIZE_CONTROLER.onStart( _currentElement, _mouseX, _mouseY) === true){\r
2465                                         currentControler = RESIZE_CONTROLER;\r
2466                                 } else {\r
2467                                         POSITION_CONTROLER.onStart( _currentElement, _mouseX, _mouseY)\r
2468                                         currentControler = POSITION_CONTROLER;\r
2469                                 }\r
2470                         },\r
2471                         onMouseMove: function( _currentElement, _mouseX, _mouseY){\r
2472                                 show( _currentElement);\r
2473                                 if( currentControler !== null){\r
2474                                         currentControler.onDrag( _mouseX, _mouseY);                                             \r
2475                                 } else {\r
2476                                         currentElement && COMIC_ELEMENT_CONSOLE.onMouseMove( _mouseX -currentx, _mouseY -currenty);\r
2477                                         TAIL_CONTROLER.hitTest( _mouseX -currentx, _mouseY -currenty) === false && RESIZE_CONTROLER.index( _mouseX, _mouseY) === -1 && MOUSE_CURSOR( '');\r
2478                                 }\r
2479                         },\r
2480                         onMouseUp: function( _currentElement, _mouseX, _mouseY){\r
2481                                 currentControler !== null && currentControler.onFinish();\r
2482                                 currentControler = null;\r
2483                         }\r
2484                 }\r
2485         })();\r
2486         /*\r
2487          *  // COMIC_ELEMENT_OPERATOR\r
2488          */\r
2489 \r
2490         var AbstractComicElement = function( JQ_WAPPER, COMIC_ELM_TYPE, update, x, y, w, h, z, timing){\r
2491                 var OPERATOR = COMIC_ELEMENT_OPERATOR;\r
2492                 return {\r
2493                         $: JQ_WAPPER,\r
2494                         type: COMIC_ELM_TYPE,\r
2495                         x: x,\r
2496                         y: y,\r
2497                         w: w,\r
2498                         h: h,                                   \r
2499                         z: z,\r
2500                         timing: timing,\r
2501                         hitareaX: function(){ return OPERATOR.hitareaX( this, this.x);},\r
2502                         hitareaY: function(){ return OPERATOR.hitareaY( this, this.y);},\r
2503                         hitareaW: function(){ return OPERATOR.hitareaW( this, this.w);},\r
2504                         hitareaH: function(){ return OPERATOR.hitareaH( this, this.h);},\r
2505                         shift: function( _shiftX, _shiftY){\r
2506                                 update( this.x +_shiftX, this.y +_shiftY);\r
2507                         },\r
2508                         busy: function(){\r
2509                                 return OPERATOR.busy();\r
2510                         },\r
2511                         onMouseMove: function( _mouseX, _mouseY){\r
2512                                 OPERATOR.onMouseMove( this, _mouseX, _mouseY);\r
2513                         },\r
2514                         onMouseUp: function( _mouseX, _mouseY){\r
2515                                 OPERATOR.onMouseUp( this, _mouseX, _mouseY);\r
2516                         },\r
2517                         onMouseDown: function( _mouseX, _mouseY){\r
2518                                 OPERATOR.onMouseDown( this, _mouseX, _mouseY);\r
2519                         }\r
2520                 }\r
2521         };\r
2522 /*\r
2523  * --------------------------------------------------------------------------------------------\r
2524  * ImageElementClass\r
2525  */\r
2526         var     jqImageElementOrigin;\r
2527         var ImageElementClass = function( url, IMAGE_SET_ID, x, y, z, w, h, timing){\r
2528                 jqImageElementOrigin = jqImageElementOrigin || $( $( '#imgElementTemplete').remove().html());\r
2529                 \r
2530                 var JQ_WRAPPER = jqImageElementOrigin.clone( true),\r
2531                         OPERATOR = COMIC_ELEMENT_OPERATOR,\r
2532                         SAVE = HISTORY.saveState,\r
2533                         HIT_AREA = MOUSE_HIT_AREA,\r
2534                         reversibleImage = null,\r
2535                         actualW = 0, actualH = 0,\r
2536                         flipH = w < 0 ? -1 : 1,\r
2537                         flipV = h < 0 ? -1 : 1,\r
2538                         instance;\r
2539                 w = Math.floor( w);\r
2540                 h = Math.floor( h);\r
2541                 \r
2542                 function update( _x, _y, _w, _h, animate){\r
2543                         instance.x = x = _x !== undefined ? _x : x;\r
2544                         instance.y = y = _y !== undefined ? _y : y;\r
2545                         instance.w = w = _w !== undefined ? _w : w;\r
2546                         instance.h = h = _h !== undefined ? _h : h;\r
2547                         JQ_WRAPPER[ animate === true ? 'animate' : 'css']( { \r
2548                                 left:   x,\r
2549                                 top:    y,\r
2550                                 width:  w,\r
2551                                 height: h\r
2552                         }, 250, function(){ reversibleImage.resize( flipH * w, flipV * h);});\r
2553                         animate !== true && reversibleImage.resize( flipH * w, flipV * h);\r
2554                 }\r
2555                 \r
2556                 function updateUrl( _url){\r
2557                         if( url === _url) return;\r
2558                         url = _url || url;\r
2559                         var _reversibleImage = pettanr.image.createReversibleImage( url, flipH * w, flipV * h, function( _url, _actualW, _actualH){\r
2560                                 actualW = _actualW;\r
2561                                 actualH = _actualH;\r
2562                         });\r
2563                         if( reversibleImage !== null){\r
2564                                 JQ_WRAPPER.children( reversibleImage.elm).replaceWith( _reversibleImage.elm);\r
2565                                 reversibleImage.destroy();\r
2566                         } else {\r
2567                                 JQ_WRAPPER.append( _reversibleImage.elm);\r
2568                         }\r
2569                         reversibleImage = _reversibleImage;\r
2570                 }\r
2571                 return pettanr.util.extend(\r
2572                         AbstractComicElement.apply( this, [ JQ_WRAPPER, COMIC_ELEMENT_TYPE_IMAGE, update, x, y, w, h, z, timing]),\r
2573                         {\r
2574                                 init: function(){\r
2575                                         instance = this;\r
2576                                         updateUrl();\r
2577                                         update();\r
2578                                         delete this.init;\r
2579                                 },\r
2580                                 flip: function( _flipH, _flipV){\r
2581                                         if( _flipH !== true && _flipV !== true) return;\r
2582                                         flipH = _flipH === true ? -flipH : flipH;\r
2583                                         flipV = _flipV === true ? -flipV : flipV;\r
2584                                         reversibleImage.resize( flipH * w, flipV * h);\r
2585                                 },\r
2586                                 flipV: function(){\r
2587                                         return flipV;\r
2588                                 },\r
2589                                 flipH: function(){\r
2590                                         return flipH;\r
2591                                 },\r
2592                                 url: function( _url, _actualW, _actualH){\r
2593                                         if( _url && _url !== url){\r
2594                                                 SAVE( updateUrl, url, _url);\r
2595                                                 actualW = _actualW;\r
2596                                                 actualH = _actualH;\r
2597                                                 updateUrl( _url);\r
2598                                         }\r
2599                                         return url;\r
2600                                 },\r
2601                                 actualW: function(){ return actualW;},\r
2602                                 actualH: function(){ return actualH;},\r
2603                                 keepSize: false,\r
2604                                 resize: update,\r
2605                                 animate: function ( _x, _y, _w, _h, _flipH, _flipV){\r
2606                                         flipH = _flipH !== undefined ? _flipH : flipH;\r
2607                                         flipV = _flipV !== undefined ? _flipV : flipV;\r
2608                                         update( _x, _y, _w, _h, true);\r
2609                                 },\r
2610                                 getAsHTML: function( isAbsoluteUrl, isXHTML){\r
2611                                         return [\r
2612                                                 '<img ',\r
2613                                                         'src="', isAbsoluteUrl !== true ? url : pettanr.util.getAbsolutePath( url), '" ',\r
2614                                                         'width="', w, '" ',\r
2615                                                         'height="', h, '" ',\r
2616                                                         'style="',                                                                      \r
2617                                                                 'left:', x, 'px;',\r
2618                                                                 'top:', y, 'px;',\r
2619                                                                 'z-index:', this.z, ';',\r
2620                                                         '"',\r
2621                                                 isXHTML !== true ? '>' : ' \/>'\r
2622                                         ].join( '');\r
2623                                 },\r
2624                                 getAsJsonString: function(){\r
2625                                         var cr = pettanr.LINE_FEED_CODE_TEXTAREA;\r
2626                                         return [\r
2627                                                 '"new', this.timing, '": {', cr,\r
2628                                                         '"resource_picture_id": 1,', cr,\r
2629                                                         '"x": ', x, ',', cr,\r
2630                                                         '"y": ', y, ',', cr,\r
2631                                                         '"z": ', this.z, ',', cr,\r
2632                                                         '"width": ', w, ',', cr,\r
2633                                                         '"height": ', h, ',', cr,\r
2634                                                         '"flipv": ', flipV === true ? 1 : 0, ',', cr,\r
2635                                                         '"fliph": ', flipH === true ? 1 : 0, ',', cr,\r
2636                                                         '"t": ', this.timing, cr,\r
2637                                                 '}'\r
2638                                         ].join( '');\r
2639                                 },\r
2640                                 destroy: function(){\r
2641                                         reversibleImage.destroy();\r
2642                                         JQ_WRAPPER.remove();\r
2643                                         JQ_WRAPPER = reversibleImage = OPERATOR = null;\r
2644                                         delete this.destroy;\r
2645                                 }\r
2646                         }\r
2647                 );\r
2648         }\r
2649 /*\r
2650  * / ImageElementClass\r
2651  * --------------------------------------------------------------------------------------------\r
2652  */\r
2653 \r
2654 \r
2655 /*\r
2656  * --------------------------------------------------------------------------------------------\r
2657  * TextElementClass\r
2658  * \r
2659  * ELM はpettanr.domで書き出したものを突っ込むcreateの場合\r
2660  * \r
2661  * type\r
2662  * 0.none\r
2663  * 1.speach balloon\r
2664  * 2.think\r
2665  * 3.bom\r
2666  * 4.black-box( dq style)\r
2667  * 5.blue-box( ff style)\r
2668  * \r
2669  */\r
2670         var jqTextElementOrigin;\r
2671         var TextElementClass = function( type, a, text, x, y, z, w, h, timing){\r
2672                 jqTextElementOrigin = jqTextElementOrigin || ( function(){\r
2673                         var _OLD_IE = $( $( '#textElementTempleteForOldIE').remove().html()),\r
2674                                 _MODERN = $( $( '#textElementTemplete').remove().html());\r
2675                         return pettanr.ua.isIE === true && pettanr.ua.ieRenderingVersion < 8 ? _OLD_IE : _MODERN;\r
2676                 })();\r
2677                 \r
2678                 var JQ_WRAPPER = jqTextElementOrigin.clone( true),\r
2679                         XBROWSER_BALLOON = pettanr.balloon.createBalloon( w, h, a, type),\r
2680                         TEXT_ELM = JQ_WRAPPER.find( 'td,.speach-inner').eq( 0),\r
2681                         OPERATOR = COMIC_ELEMENT_OPERATOR,\r
2682                         HIT_AREA = MOUSE_HIT_AREA,\r
2683                         SAVE = HISTORY.saveState,\r
2684                         instance;\r
2685                         \r
2686                 JQ_WRAPPER.find( 'img').eq( 0).replaceWith( XBROWSER_BALLOON.elm);\r
2687                 \r
2688                 function update( _x, _y, _w, _h, _a, animate){\r
2689                         instance.x = x = _x !== undefined ? _x : x;\r
2690                         instance.y = y = _y !== undefined ? _y : y;\r
2691                         instance.w = w = _w !== undefined ? _w : w;\r
2692                         instance.h = h = _h !== undefined ? _h : h;\r
2693                         a = _a !== undefined ? _a : a;\r
2694                         \r
2695                         JQ_WRAPPER[ animate === true ? 'animate' : 'css']( {\r
2696                                         left:           x,\r
2697                                         top:            y,\r
2698                                         width:          w,\r
2699                                         height:         h\r
2700                                 }, 250,\r
2701                                 function(){\r
2702                                         XBROWSER_BALLOON.resize( a, w, h);\r
2703                                 }\r
2704                         );              \r
2705                         animate !== true && XBROWSER_BALLOON.resize( a, w, h);\r
2706                 }\r
2707                 \r
2708                 function updateType( _type){\r
2709                         if( type !== _type){\r
2710                                 type = _type || type;\r
2711                                 XBROWSER_BALLOON.type( type);\r
2712                         }\r
2713                 }\r
2714                 function updateAngle( _a){\r
2715                         if( _a !== undefined && a !== _a){\r
2716                                 a = _a !== undefined ? _a : a;\r
2717                                 XBROWSER_BALLOON.angle( a);\r
2718                         }\r
2719                 }\r
2720                 function updateText( _text){\r
2721                         text = _text || text || '';\r
2722                         TEXT_ELM.html( text);\r
2723                 }\r
2724                 \r
2725                 return pettanr.util.extend(\r
2726                         AbstractComicElement.apply( this, [ JQ_WRAPPER, COMIC_ELEMENT_TYPE_TEXT, update, x, y, w, h, z, timing]),\r
2727                         {\r
2728                                 init: function(){\r
2729                                         instance = this;\r
2730                                         updateText();\r
2731                                         update();\r
2732                                         delete this.init;\r
2733                                 },\r
2734                                 angle: function( _a){\r
2735                                         _a !== undefined && update( undefined, undefined, undefined, undefined, _a);\r
2736                                         return a;\r
2737                                 },\r
2738                                 text: function( _text){\r
2739                                         if( _text && text !== _text) {\r
2740                                                 SAVE( updateText, text || '', _text);\r
2741                                                 updateText( _text);\r
2742                                         }\r
2743                                         return text;\r
2744                                 },\r
2745                                 resize: update,\r
2746                                 animate: function ( _x, _y, _w, _h, _a){\r
2747                                         update( _x, _y, _w, _h, _a, true);\r
2748                                 },\r
2749                                 destroy: function(){\r
2750                                         JQ_WRAPPER.remove();\r
2751                                         XBROWSER_BALLOON.destroy();\r
2752                                         OPERATOR = null;\r
2753                                         delete this.destroy;\r
2754                                 },\r
2755                                 getAsJSON: function(){\r
2756                                         \r
2757                                 },\r
2758                                 getAsJsonString: function(){\r
2759                                         var cr = pettanr.LINE_FEED_CODE_TEXTAREA;\r
2760                                         return [\r
2761                                                 '"new', this.timing, '": {', cr,\r
2762                                                         '"balloon_template_id": ', 1, ',', cr,\r
2763                                                         '"system_picture_id": ', 1, ',', cr,\r
2764                                                         '"size": ', 1, ',', cr,\r
2765                                                         '"tail": ', a, ',', cr,\r
2766                                                         '"x": ', x, ',', cr,\r
2767                                                         '"y": ', y, ',', cr,\r
2768                                                         '"z": ', this.z, ',', cr,\r
2769                                                         '"t": ', this.timing, ',', cr,\r
2770                                                         '"width": ', w, ',', cr,\r
2771                                                         '"height": ', h, ',', cr,\r
2772                                                         '"speaches_attributes": {', cr,\r
2773                                                         '"newf', this.timing, '": {', cr,\r
2774                                                         '"content": "', text, '",', cr,\r
2775                                                                         '"x": ', x, ',', cr,\r
2776                                                                         '"y": ', y, ',', cr,\r
2777                                                                         '"t": ', 0, ',', cr,\r
2778                                                                         '"width": ', w, ',', cr,\r
2779                                                                         '"height": ', h, cr,\r
2780                                                                 '}', cr,\r
2781                                                         '}', cr,\r
2782                                                 '}'\r
2783                                         ].join( '');\r
2784                                 },\r
2785                                 getAsHTML: function( isAbsoluteUrl, isXHTML){\r
2786                                         var url = XBROWSER_BALLOON.getURL();\r
2787                                         return [\r
2788                                                 '<img ',\r
2789                                                         'src="', isAbsoluteUrl !== true ? url : pettanr.util.getAbsolutePath( url), '" ',\r
2790                                                         'width="', w, '" ',\r
2791                                                         'height="', h, '" ',\r
2792                                                         'style="',                                                                      \r
2793                                                                 'left:', x, 'px;',\r
2794                                                                 'top:', y, 'px;',\r
2795                                                                 'z-index:', this.z, ';',\r
2796                                                         '"',\r
2797                                                 isXHTML !== true ? '>' : ' \/>',\r
2798                                                 pettanr.LINE_FEED_CODE_TEXTAREA,\r
2799                                                 '<div class="balloon" style="',\r
2800                                                         'left:', x, 'px;',\r
2801                                                         'top:', y, 'px;',\r
2802                                                         'width:', w, 'px;',\r
2803                                                         'height:', h, 'px;',\r
2804                                                         'z-index:', this.z,\r
2805                                                 '"><span>', text, '<\/span>', '<\/div>'\r
2806                                                         \r
2807                                         ].join( '');\r
2808                                 },\r
2809                                 getAsXML: function(){}\r
2810                                 \r
2811                         }\r
2812                 );\r
2813         }\r
2814 \r
2815 \r
2816         var COMIC_ELEMENT_CONTROL = ( function(){\r
2817                 var     currentElement = null,\r
2818                         canvasX, canvasY, canvasW, canvasH,\r
2819                         startX, startY;\r
2820         \r
2821         /*\r
2822          * append, remove, replace\r
2823          * \r
2824          * comicElement には、z-position と dom-index がある。\r
2825          *   z-position は 表示上の位置。大きいほど前に表示される( z-index)\r
2826          *   dom-index は 意味上の順番。htmlタグの登場順で、検索結果や音声読み上げブラウザで正しく意味が取れる順番。\r
2827          * \r
2828          * editerでは、実際には z-index は使わず、htmlの順序で前後を表現する。\r
2829          * dom-index は、数値のみ保持して、投稿時にcomicElementを適宜に並び替える。\r
2830          * \r
2831          * append comicElement\r
2832          * 1. 新しい comicElement の z-position を得る\r
2833          * 2. z の同じ comicElementを見つけ、その前に加える。または一番先頭へ。(DRAGGABLE_ELEMENT_ARRAY)\r
2834          *    zが大きいほど、DRAGGABLE_ELEMENT_ARRAYの先頭へ。\r
2835          * 3. dom位置は、DRAGGABLE_ELEMENT_ARRAY とは反対に、前のものほど後ろへ。\r
2836          * \r
2837          * \r
2838          * remove comicElement\r
2839          * 1. remove\r
2840          * 2. renumber z\r
2841          */\r
2842                 function appendComicElement( _comicElement) {\r
2843                         _comicElement.init && _comicElement.init();\r
2844                         var z = _comicElement.z,\r
2845                                 l = DRAGGABLE_ELEMENT_ARRAY.length;\r
2846                         _comicElement.$.stop().css( {\r
2847                                 filter:         '',\r
2848                                 opacity:        ''\r
2849                         });\r
2850                         if( z === undefined || z === NaN || z < 0 || z >= l){\r
2851                                 DRAGGABLE_ELEMENT_ARRAY.unshift( _comicElement);\r
2852                                 comicElementContainer.append( _comicElement.$.fadeIn());\r
2853                         } else {\r
2854                                 var insertIndex = ( function(){\r
2855                                                 for( var ret = 0; ret < l; ++ret){\r
2856                                                         if( DRAGGABLE_ELEMENT_ARRAY[ ret].z <= z) return ret +1;\r
2857                                                 }\r
2858                                                 return 0;\r
2859                                         })();\r
2860                                 DRAGGABLE_ELEMENT_ARRAY[ insertIndex -1].$.after( _comicElement.$.fadeIn());\r
2861                                 DRAGGABLE_ELEMENT_ARRAY.splice( insertIndex, 0, _comicElement);\r
2862                         }\r
2863                         sortComicElement();\r
2864                 }\r
2865                 function removeComicElement( _comicElement) {\r
2866                         var l = DRAGGABLE_ELEMENT_ARRAY.length;\r
2867                         for( var i=0; i<l; ++i){\r
2868                                 if( DRAGGABLE_ELEMENT_ARRAY[ i] === _comicElement){\r
2869                                         DRAGGABLE_ELEMENT_ARRAY.splice( i, 1);\r
2870                                         sortComicElement();\r
2871                                         _comicElement.$.stop().css( {\r
2872                                                 filter:         '',\r
2873                                                 opacity:        ''\r
2874                                         }).fadeOut( function(){\r
2875                                                 this.parentNode.removeChild( this);\r
2876                                         });\r
2877                                         currentElement = currentElement === _comicElement ? null : currentElement;\r
2878                                         return;\r
2879                                 }\r
2880                         }\r
2881                 }\r
2882                 function restoreComicElement( arg){\r
2883                         var isAppend = arg[ 0],\r
2884                                 comicElement = arg[ 1];\r
2885                         isAppend === true ? appendComicElement( comicElement) : removeComicElement( comicElement);\r
2886                 }\r
2887                 /*\r
2888                  * DRAGGABLE_ELEMENT_ARRAY の順番を基準に、zの再計算\r
2889                  * jqElmの並び替え。\r
2890                  */\r
2891                 function sortComicElement(){\r
2892                         var l = DRAGGABLE_ELEMENT_ARRAY.length,\r
2893                                 _comicElement, jqElm, jqNext;\r
2894                         for( var i=0; i < l; ++i){\r
2895                                 _comicElement = DRAGGABLE_ELEMENT_ARRAY[ i];\r
2896                                 jqElm = _comicElement.$;\r
2897                                 jqNext && jqNext.before( jqElm);\r
2898                                 _comicElement.z = l -i +1;\r
2899                                 jqNext = jqElm;\r
2900                         }\r
2901                 }\r
2902                 function replaceComicElement( _comicElement, goForward){\r
2903                         // DRAGGABLE_ELEMENT_ARRAYの再構築\r
2904                         var l = DRAGGABLE_ELEMENT_ARRAY.length,\r
2905                                 i = ( function(){\r
2906                                         for( var ret = 0; ret < l; ++ret){\r
2907                                                 if( DRAGGABLE_ELEMENT_ARRAY[ ret] === _comicElement) return ret;\r
2908                                         }\r
2909                                         return -1;\r
2910                                 })();\r
2911                         if( i === -1) return;\r
2912                         if( goForward === true){\r
2913                                 if( i === 0) return;\r
2914                                 DRAGGABLE_ELEMENT_ARRAY.splice( i, 1);\r
2915                                 DRAGGABLE_ELEMENT_ARRAY.splice( i -1, 0, _comicElement);\r
2916                         } else {\r
2917                                 if( i === l -1) return;\r
2918                                 DRAGGABLE_ELEMENT_ARRAY.splice( i, 1);\r
2919                                 DRAGGABLE_ELEMENT_ARRAY.splice( i +1, 0, _comicElement);\r
2920                         }\r
2921                         sortComicElement();\r
2922                 }\r
2923                 function restoreReplaceObject( arg){\r
2924                         replaceComicElement( arg[ 0], arg[ 1]);\r
2925                 }\r
2926                 \r
2927                 return {\r
2928                         init: function( _x, _y, _w, _h){\r
2929                         /*\r
2930                          * comic-element\r
2931                          */\r
2932                                 comicElementContainer = $( '#comic-element-container');\r
2933                                 \r
2934                                 appendComicElement( ImageElementClass.apply( {}, [ 'images/13.gif', 'penchan', 10, 10, 0, 100, 140, 0]));\r
2935                                 appendComicElement( TextElementClass.apply( {}, [ 0, 270, 'Hello', 50, 70, 1, 200, 160, 1]));\r
2936                                 \r
2937                                 COMIC_ELEMENT_OPERATOR.init( updateMouseCursor);\r
2938                         /*\r
2939                          * \r
2940                          */\r
2941                                 log = $( '#operation-catcher-log');\r
2942 \r
2943                                 this.onCanvasResize( _x, _y, _w, _h);\r
2944                                 \r
2945                                 delete COMIC_ELEMENT_CONTROL.init;\r
2946                         },\r
2947                         removeComicElement: removeComicElement,\r
2948                         restoreComicElement: restoreComicElement,\r
2949                         replaceComicElement: replaceComicElement,\r
2950                         restoreReplaceObject: restoreReplaceObject,\r
2951                         onCanvasResize : function ( _canvasX, _canvasY, _canvasW, _canvasH, isResizerTopAction){\r
2952                         /*\r
2953                          * リサイズが、ResizerTopによって行われた場合、comicElementのyを動かして見かけ上動かないようにする。\r
2954                          */                                     \r
2955                                 if( isResizerTopAction === true){\r
2956                                         var     _shiftX = _canvasW -canvasW,\r
2957                                                 _shiftY = _canvasH -canvasH,\r
2958                                                 l = DRAGGABLE_ELEMENT_ARRAY.length;\r
2959                                         for( var i = 0; i < l; i++){\r
2960                                                 DRAGGABLE_ELEMENT_ARRAY[ i].shift( _shiftX, _shiftY);\r
2961                                         }\r
2962                                 }\r
2963                                 canvasX = _canvasX;\r
2964                                 canvasY = _canvasY;\r
2965                                 canvasW = _canvasW;\r
2966                                 canvasH = _canvasH;\r
2967                                 \r
2968                                 comicElementContainer.css( {\r
2969                                         width:  _canvasW,\r
2970                                         height: _canvasH,\r
2971                                         left:   _canvasX,\r
2972                                         top:    _canvasY\r
2973                                 });\r
2974                         },\r
2975                         onMouseMove: function( _mouseX, _mouseY){\r
2976                                 var l = DRAGGABLE_ELEMENT_ARRAY.length,\r
2977                                         _X = _mouseX -canvasX,\r
2978                                         _Y = _mouseY -canvasY,\r
2979                                         _elm, _x, _y;\r
2980                                         \r
2981                                 if( currentElement !== null){\r
2982                                         if( currentElement.busy() === true){\r
2983                                                 currentElement.onMouseMove( _X, _Y);\r
2984                                                 return true;\r
2985                                         }\r
2986                                         _x = currentElement.hitareaX();\r
2987                                         _y = currentElement.hitareaY();\r
2988                                         if( _x <= _X && _y <= _Y && _x + currentElement.hitareaW() >= _X && _y +currentElement.hitareaH() >= _Y){\r
2989                                                 currentElement.onMouseMove( _X, _Y); // cursor\r
2990                                                 return true;\r
2991                                         }\r
2992                                 }\r
2993                                 for( var i=0; i<l; i++){\r
2994                                         _elm = DRAGGABLE_ELEMENT_ARRAY[ i];\r
2995                                         _x = _elm.hitareaX();\r
2996                                         _y = _elm.hitareaY();\r
2997                                         // hitTest\r
2998                                         if( _x <= _X && _y <= _Y && _x + _elm.hitareaW() >= _X && _y +_elm.hitareaH() >= _Y){\r
2999                                                 currentElement = _elm;\r
3000                                                 currentElement.onMouseMove( _X, _Y); // cursor\r
3001                                                 log.html( [ _X, _Y, _x, _y, i].join( ','));\r
3002                                                 return true;\r
3003                                         }\r
3004                                 }\r
3005                                 currentElement = null;                                                  \r
3006                                 COMIC_ELEMENT_OPERATOR.hide();\r
3007                                 log.html( [ _X, _Y, _x, _y].join( ','));\r
3008                                 return false;\r
3009                         },\r
3010                         onMouseUp: function( _mouseX, _mouseY){\r
3011                                 var ret = currentElement !== null && currentElement.busy() === true;\r
3012                                 ret === true && currentElement.onMouseUp( _mouseX -startX || canvasX, _mouseY -startY || canvasY);\r
3013                                 startX = startY = NaN;\r
3014                                 return ret;\r
3015                         },\r
3016                         onMouseDown: function( _mouseX, _mouseY){\r
3017                                 startX = canvasX;\r
3018                                 startY = canvasY;\r
3019                                 currentElement !== null && currentElement.onMouseDown( _mouseX -startX, _mouseY -startY);\r
3020                                 return currentElement !== null;\r
3021                         },\r
3022                         busy: function(){\r
3023                                 return currentElement !== null;\r
3024                         },\r
3025                         createImageElement: function( url, imagesetID, x, y, z, w, h){\r
3026                                 w = w || 200; //ActualWidth\r
3027                                 h = h || 150; //ActualHeight\r
3028                                 x = x || Math.floor( canvasW /2 -w /2);\r
3029                                 y = y || Math.floor( canvasH /2 -h /2);\r
3030                                 IMAGE_GROUP_EXPROLER.show( function( _url, _w, _h){\r
3031                                         var _comicElement = ImageElementClass.apply( {}, [ _url, imagesetID, x, y, z || -1, w, h, DRAGGABLE_ELEMENT_ARRAY.length]);\r
3032                                         appendComicElement( _comicElement);\r
3033                                         _comicElement.animate( undefined, undefined, _w, _h);\r
3034                                         SAVE( restoreComicElement, [ false, _comicElement], [ true, _comicElement], true);\r
3035                                 });\r
3036                         },\r
3037                         createTextElement: function( type, angle, text, x, y, z, w, h){\r
3038                                 type = type || 0;\r
3039                                 angle = angle || 0;\r
3040                                 text = text || '';\r
3041                                 w = w || 200;\r
3042                                 h = h || 150;\r
3043                                 x = x || Math.floor( canvasW /2 -w /2 +Math.random() *10);\r
3044                                 y = y || Math.floor( canvasH /2 -h /2 +Math.random() *10);\r
3045                                 var _comicElement = TextElementClass.apply( {}, [ type, angle, text, x, y, z || -1, w, h, DRAGGABLE_ELEMENT_ARRAY.length]);\r
3046                                 TEXT_EDITOR_CONTROL.show( _comicElement, function( _comicElement){\r
3047                                         appendComicElement( _comicElement);\r
3048                                         SAVE( restoreComicElement, [ false, _comicElement], [ true, _comicElement], true);\r
3049                                 });\r
3050                         },\r
3051                         getAsHTML: function( isAbsoluteUrl, isXHTML){\r
3052                                 var HTML_ARRAY = [],\r
3053                                         l = DRAGGABLE_ELEMENT_ARRAY.length,\r
3054                                         _timing = 0,\r
3055                                         _comicElement;\r
3056 \r
3057                                 while( HTML_ARRAY.length < l){\r
3058                                         _comicElement = getComicElementByTiming();\r
3059                                         if( _comicElement === null) break;\r
3060                                         HTML_ARRAY.push( _comicElement.getAsHTML( isAbsoluteUrl, isXHTML));\r
3061                                 }\r
3062                                 function getComicElementByTiming(){\r
3063                                         while( _timing < l *2){\r
3064                                                 for(var i=0; i<l; ++i){\r
3065                                                         if( _timing === DRAGGABLE_ELEMENT_ARRAY[ i].timing){\r
3066                                                                 ++_timing;\r
3067                                                                 return DRAGGABLE_ELEMENT_ARRAY[ i];\r
3068                                                         }\r
3069                                                 }\r
3070                                                 ++_timing;\r
3071                                         }\r
3072                                         return null;\r
3073                                 }\r
3074                                 HTML_ARRAY.unshift(\r
3075                                         [\r
3076                                                 '<div class="panel" ',\r
3077                                                         'style="',\r
3078                                                                 'height:', canvasH, 'px;',\r
3079                                                                 'background-color:', ';',\r
3080                                                         '"',\r
3081                                                 '>'\r
3082                                         ].join( '')\r
3083                                 );              \r
3084                                 HTML_ARRAY.push( '</div>');\r
3085                                 \r
3086                                 return HTML_ARRAY.join( pettanr.LINE_FEED_CODE_TEXTAREA);\r
3087                         },\r
3088                         getAsJsonString: function(){\r
3089                                 var JSON_STRING_ARRAY = [],\r
3090                                         IMAGE_ARRAY = [],\r
3091                                         BALLOON_ARRAY = [],\r
3092                                         l = DRAGGABLE_ELEMENT_ARRAY.length,\r
3093                                         _timing = 0,\r
3094                                         _comicElement,\r
3095                                         cr = pettanr.LINE_FEED_CODE_TEXTAREA;\r
3096                                         \r
3097                                 while( IMAGE_ARRAY.length + BALLOON_ARRAY.length < l){\r
3098                                         _comicElement = getComicElementByTiming();\r
3099                                         if( _comicElement === null) break;\r
3100                                         _comicElement.type === COMIC_ELEMENT_TYPE_IMAGE ? \r
3101                                                 IMAGE_ARRAY.push( _comicElement.getAsJsonString()) :\r
3102                                                 BALLOON_ARRAY.push( _comicElement.getAsJsonString());\r
3103                                 }\r
3104                                 function getComicElementByTiming(){\r
3105                                         while( _timing < l *2){\r
3106                                                 for(var i=0; i<l; ++i){\r
3107                                                         if( _timing === DRAGGABLE_ELEMENT_ARRAY[ i].timing){\r
3108                                                                 ++_timing;\r
3109                                                                 return DRAGGABLE_ELEMENT_ARRAY[ i];\r
3110                                                         }\r
3111                                                 }\r
3112                                                 ++_timing;\r
3113                                         }\r
3114                                         return null;\r
3115                                 }\r
3116                                 return [\r
3117                                         '{', cr,\r
3118                                                 '"panel": {', cr,\r
3119                                                     '"border": 1,', cr,\r
3120                                                     '"comic_id": 5,', cr,\r
3121                                                     '"resource_picture_id": 1,', cr,\r
3122                                                         '"x": ', 0, ',', cr,\r
3123                                                         '"y": ', 0, ',', cr,\r
3124                                                         '"z": ', 0, ',', cr,\r
3125                                                         '"t": ', 0, ',', cr,\r
3126                                                     '"width": ', canvasW, ',', cr,\r
3127                                                     '"height": ', canvasH, ',', cr,\r
3128                                                     '"panel_pictures_attributes": {', cr,\r
3129                                                         IMAGE_ARRAY.join( ',' +cr), cr,\r
3130                                                     '},', cr,\r
3131                                                     '"balloons_attributes": {', cr,\r
3132                                                         BALLOON_ARRAY.join( ',' +cr), cr,\r
3133                                                     '}', cr,\r
3134                                                 '}', cr,\r
3135                                         '}'\r
3136                                 ].join( '');\r
3137                         }\r
3138                 }\r
3139         })();\r
3140         \r
3141         /*\r
3142          * end of COMIC_ELEMENT_CONTROL\r
3143          */\r
3144 \r
3145 \r
3146 \r
3147         function updateMouseCursor( _cursor){\r
3148                 if( currentCursor !== _cursor){\r
3149                         currentCursor = _cursor;\r
3150                         setTimeout( update, 0);\r
3151                 }\r
3152                 function update(){\r
3153                         ELM_MOUSE_EVENT_CHATCHER.style.cursor = currentCursor;\r
3154                 }\r
3155         }\r
3156         function centering(){\r
3157                 pettanr.editor.onWindowResize( windowW, windowH);\r
3158         }       \r
3159         function mouseEventRellay( e){\r
3160                 var _mouseX = e.pageX,\r
3161                         _mouseY = e.pageY,\r
3162                         rellayMethod = e.type === 'mousedown' ?\r
3163                                         'onMouseDown' :\r
3164                                         ( e.type === 'mousemove' ? 'onMouseMove' : 'onMouseUp');\r
3165                 if( currentListener !== null && currentListener.busy() === true){\r
3166                         currentListener[ rellayMethod]( _mouseX, _mouseY);\r
3167                 } else {\r
3168                         currentListener = null;\r
3169                         var l = MOUSE_LISTENER_ARRAY.length,\r
3170                                 _listener;\r
3171                         for( var i=0; i<l; ++i){\r
3172                                 _listener = MOUSE_LISTENER_ARRAY[ i];\r
3173                                 if( _listener[ rellayMethod]( _mouseX, _mouseY) === true){\r
3174                                         currentListener = _listener;\r
3175                                         break;\r
3176                                 }\r
3177                         }\r
3178                 }\r
3179                 // 文字選択の禁止\r
3180                 //!document.selection && window.getSelection().removeAllRanges();\r
3181                 e.stopPropagation();\r
3182                 return false;\r
3183         }\r
3184 \r
3185         return {\r
3186                 init: function( _option){\r
3187                         option = _option;\r
3188                 },\r
3189                 firstOpen: function(){\r
3190                         var jqWindow = pettanr.jqWindow();\r
3191                         windowW = jqWindow.width();\r
3192                         windowH = jqWindow.height();\r
3193                         \r
3194                         jqEditor = $( '#editor');\r
3195 \r
3196                         pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 96, false, true, centering);\r
3197                         pettanr.key.addKeyDownEvent( pettanr.view.EDITOR, 48, false, true, centering);\r
3198 \r
3199                 /*\r
3200                  * MOUSE_LISTENER_ARRAY は、表示順に格納.手前の要素が最初\r
3201                  * MENU_BAR_CONTROL,\r
3202                  * WINDOW_CONTROL,\r
3203                  * COMIC_ELEMENT_CONTROL,\r
3204                  * CANVAS_CONTROL\r
3205                  * .busy() === true なら、そのままonMouseMove()にイベントを流す.これはArrayの後ろから、奥の表示要素から\r
3206                  * onMouseMove()に流してみて、false が帰れば、次にリスナーにも流す.\r
3207                  */\r
3208                         MOUSE_LISTENER_ARRAY.push( MENU_BAR_CONTROL, WINDOWS_CONTROL, PANEL_RESIZER_TOP, PANEL_RESIZER_BOTTOM, COMIC_ELEMENT_CONTROL, PANEL_CONTROL);\r
3209 \r
3210                         HISTORY.init();\r
3211                         MENU_BAR_CONTROL.EDIT.createSelection( 'centering', 'ctrl + 0', centering, true, true, true);\r
3212                         \r
3213                         WINDOWS_CONTROL.init();\r
3214                         \r
3215                         GRID_CONTROL.init();\r
3216                         // WHITE_GLASS_CONTROL.init();\r
3217                         PANEL_CONTROL.init();\r
3218                         //COMIC_ELEMENT_CONTROL.init();\r
3219                         \r
3220                         // last\r
3221                         MENU_BAR_CONTROL.init();\r
3222                         \r
3223                         \r
3224                         \r
3225                         TEXT_EDITOR_CONTROL.init();\r
3226                         IMAGE_GROUP_EXPROLER.init();\r
3227                 /*\r
3228                  * jqMouseEventChacher は透明な要素で、\r
3229                  * マウスイベントをcurrentElement(currentElement)に伝えるのが仕事\r
3230                  * このような実装になるのは、ここの表示オブジェクトにイベントを設定した場合、表示が追いつかずマウスカーソルが外れたタイミングでイベントが終わってしまうため。\r
3231                  */                     \r
3232                         jqMouseEventChacher = $( ELM_MOUSE_EVENT_CHATCHER)\r
3233                                 .mousemove( mouseEventRellay)\r
3234                                 .mousedown( mouseEventRellay)\r
3235                                 .mouseup( mouseEventRellay)\r
3236                                 .mouseout( mouseEventRellay);\r
3237                         \r
3238                         delete pettanr.editor.firstOpen;\r
3239                 },\r
3240                 onOpen: function( _option){\r
3241                         pettanr.editor.firstOpen !== undefined && pettanr.editor.firstOpen();\r
3242 \r
3243                         // HISTORY.onOpen();\r
3244                         // WINDOWS_CONTROL.onOpen();\r
3245                         // COMIC_ELEMENT_CONTROL.onOpen();\r
3246                         // MENU_BAR_CONTROL.onOpen();\r
3247                         // TEXT_EDITOR_CONTROL.onOpen();\r
3248                         // IMAGE_GROUP_EXPROLER.onOpen();\r
3249                 },\r
3250                 onClose: function(){\r
3251                 },\r
3252                 onWindowResize: function( _windowW, _windowH){\r
3253                         windowW = _windowW;\r
3254                         windowH = _windowH;\r
3255                         \r
3256                         /*\r
3257                          * ieは +'px'が不要みたい\r
3258                          */\r
3259                         jqEditor.get( 0).style.height = _windowH +'px';\r
3260                         ELM_MOUSE_EVENT_CHATCHER.style.height = _windowH +'px';\r
3261                         \r
3262                         WINDOWS_CONTROL.onWindowResize( _windowW, _windowH);\r
3263                         MENU_BAR_CONTROL.onWindowResize( _windowW, _windowH);\r
3264                         PANEL_CONTROL.onWindowResize( _windowW, _windowH);\r
3265                 },\r
3266                 MIN_WIDTH:      320,\r
3267                 MIN_HEIGHT:     320\r
3268         }\r
3269 })();\r