OSDN Git Service

Version 0.6.97, rename X.Dom.Image -> X.Util.Image.
[pettanr/clientJs.git] / 0.3.0 / work.js
1 /*\r
2  * pettanR work.js\r
3  *   version 0.3.0\r
4  *   \r
5  * author:\r
6  *   itozyun\r
7  * licence:\r
8  *   new BSD\r
9  *\r
10  * \r
11  * ----------------------------------------\r
12  * - naming of comic's elements -\r
13  * \r
14  *  0.comic strip(en) : koma manga(jp)\r
15  *\r
16  *  1.panel(en) : koma(jp)\r
17  *    +------------+\r
18  *    |            |\r
19  *    |            |\r
20  *    |            |\r
21  *    |            |\r
22  *    +------------+\r
23  *  \r
24  *  2.speach balloon(en) : fukidasi(jp)\r
25  *      ________\r
26  *     /        \\r
27  *     |         |\r
28  *    <  Hello!! |\r
29  *     |         |\r
30  *     \________/\r
31  *   \r
32  *  3.img\r
33  * \r
34  * \r
35  * ----------------------------------------\r
36  * window\r
37  * +----------------------------+\r
38  * |      CANVAS_CONTROL        |  \r
39  * |       - panel              |\r
40  * |        +----------+        | \r
41  * |        | +----------+      | \r
42  * |        | |          |      | \r
43  * |        | |          |      | \r
44  * |        +-|          |      |\r
45  * |          +----------+      | \r
46  * |        - WHITE_GLASS_CONTROL | \r
47  * +----------------------------+\r
48  * \r
49  * ----------------------------------------\r
50  * naming rules\r
51  * \r
52  *  Class\r
53  *    ThisIsClass\r
54  *  \r
55  *  const & Singleton Class\r
56  *    THIS_IS_CONST = 'this is const';\r
57  *  \r
58  *  var\r
59  *    thisIsVar\r
60  *   \r
61  *  value of jquery\r
62  *    jqWrapper, JQ_WRAPPER\r
63  *  \r
64  *  value of dom element\r
65  *    elmWrapper, ELM_WRAP\r
66  * \r
67  *      value of vml element\r
68  *    vmkImg, VML_SHAPE\r
69  * \r
70  */\r
71 \r
72 var h2c = ( function(){\r
73         var     FUNCTION_ARRAY = [],\r
74                 URL = document.location.href.split( '#')[ 0],\r
75                 IS_LOCAL = URL.indexOf( 'file:') === 0,\r
76                 URL_PARAMS = ( function(){\r
77                         var search = document.location.search,\r
78                                 l = search.length;\r
79                     if( 1 < l){\r
80                         var     query = search.substring( 1),\r
81                                         params = query.split( '&'),\r
82                                         ret = {}, elm, name;\r
83                         while( params.length > 0){\r
84                             elm = params.shift().split( '=');\r
85                                         name = decodeURIComponent( elm[ 0]);\r
86                                         if( elm.length === 2){\r
87                                     ret[ name] = ( function( v){\r
88                                                         if( '' + parseFloat( v) === v) return parseFloat( v);\r
89                                                         if( v === 'true') return true;\r
90                                                         if( v === 'false') return false;\r
91                                                         if( v === 'null') return null;\r
92                                                         if( v === 'undefined') return undefined;\r
93                                                         return v;\r
94                                                 })( decodeURIComponent( elm[ 1]));\r
95                                         } else\r
96                                         if( elm.length === 1){\r
97                                                 ret[ name] = true;\r
98                                         }\r
99                         }\r
100                         return ret;\r
101                     }\r
102                     return {};\r
103                 })(),\r
104                 IS_DEBUG = IS_LOCAL === true || URL_PARAMS.debug === true,\r
105                 isIE = navigator.userAgent.toLowerCase().indexOf( 'msie') !== -1,\r
106                 ieVersion = isIE === true ? parseInt( navigator.appVersion.toLowerCase().replace( /.*msie[ ]/, '').match( /^[0-9]+/)) : 0,\r
107                 ieMode = ieVersion === 8 ? document.documentMode : 0,\r
108                 isStanderdMode = document.compatMode === 'CSS1Compat',\r
109                 jqWindow , jqDocument , jqBody;\r
110         return {\r
111                 version: '0.3.0',\r
112                 init: function(){\r
113                         jqWindow = $( window);\r
114                         jqDocument = $( document);\r
115                         jqBody = $( document.body);\r
116                         \r
117                         var l = FUNCTION_ARRAY.length,\r
118                                 _fn;\r
119                         for( var i=0; i<l; i++){\r
120                                 _fn = FUNCTION_ARRAY[ i];\r
121                                 _fn.init && _fn.init( _fn === h2c.view ? FUNCTION_ARRAY : undefined);\r
122                         }\r
123                         \r
124                         delete h2c.init;\r
125                 },\r
126                 fn: function( _fn){\r
127                         FUNCTION_ARRAY.push( _fn);\r
128                         h2c.init === undefined && _fn.init && _fn.init();\r
129                 },\r
130                 isIE: isIE,\r
131                 ieVersion: ieVersion,\r
132                 ieRenderingVersion: ieMode !== 0 ? ieMode : ieVersion,\r
133                 isStanderdMode: isStanderdMode,\r
134                 VENDER_PREFIX: ( function() {\r
135                         var ua = navigator.userAgent.toLowerCase();\r
136                         if ( ua.indexOf('opera') !== -1) {\r
137                                 return 'O';\r
138                         } else if ( ua.indexOf('msie') !== -1) {\r
139                                 return 'ms';\r
140                         } else if ( ua.indexOf('webkit') !== -1) {\r
141                                 return 'webkit';\r
142                         } else if ( navigator.product === 'Gecko') {\r
143                                 return 'Moz';\r
144                         }\r
145                         return '';\r
146                 })(),\r
147                 ACTIVEX: ( function(){\r
148                         if( isIE === false || ieVersion > 8) return false;\r
149                         var className = document.body.className,\r
150                                 test;\r
151                         if( className && className.indexOf( 'h2c-ActiveX-enabled') !== -1) return true;\r
152                         if( className && className.indexOf( 'h2c-ActiveX-disabled') !== -1) return false;\r
153                         try {\r
154                                 test = new ActiveXObject('DXImageTransform.Microsoft.gradient');\r
155                         } catch( e){\r
156                                 return false;\r
157                         }\r
158                         return !!test;\r
159                 })(),\r
160                 VML: ( function(){\r
161                         if( isIE === false || ieVersion > 8) return false;\r
162                         var globalObjectName = '_global',\r
163                                 script;\r
164                         document.write( [ '<!--[if gte vml 1]><script>window', globalObjectName, '=1;<\/script><![endif]-->'].join( ''));\r
165                         if( window[globalObjectName] === 1){\r
166                                 //script = document.getElementById( globalObjectName);\r
167                                 //script.parentNode.removeChild( script);\r
168                                 window[globalObjectName] = undefined;\r
169                                 return true;\r
170                         }\r
171                         return false;\r
172                 })(),\r
173                 startVML: function(){\r
174                         if( h2c.VML !== true) return false;\r
175                         if (!document.namespaces["v"]) {\r
176                         document.namespaces.add("v", "urn:schemas-microsoft-com:vml", "#default#VML");\r
177                     }\r
178                     document.createStyleSheet().cssText = "v\:shape,v\:image{behavior:url(#default#VML);display:block;};";\r
179                     delete this.startVML;\r
180                 },\r
181                 jqWindow: function(){\r
182                         return jqWindow;\r
183                 },\r
184                 jqDocument: function(){\r
185                         return jqDocument;\r
186                 },\r
187                 jqBody: function(){\r
188                         return jqBody;\r
189                 },\r
190                 URL_PARAMS: URL_PARAMS,\r
191                 LOCAL: IS_LOCAL,\r
192                 DEBUG: IS_DEBUG,\r
193                 LINE_FEED_CODE_TEXTAREA : ( function(){\r
194                         var text = document.getElementById( 'shadowTxtarea'),\r
195                                 form = text.parentNode;\r
196                         form.parentNode.removeChild( form);\r
197                         return text.value;\r
198                 })(),\r
199                 LINE_FEED_CODE_PRE : ( function(){\r
200                         var pre = document.getElementById( 'shadowPre');\r
201                         pre.parentNode.removeChild( pre);\r
202                         return isIE === true ? this.LINE_FEED_CODE_TEXTAREA : pre.innerHTML; // ie ??\r
203                 })()\r
204         }\r
205 })();\r
206 \r
207 /*\r
208  * h2c.util\r
209  * \r
210  * getElementSize( _elm)\r
211  * getImageSize()\r
212  * \r
213  */\r
214 h2c.util = ( function(){\r
215         var ELM_SIZE_GETTER = ( function(){\r
216                         var ret = document.createElement( 'DIV'),\r
217                                 style = ret.style;\r
218                         ret.id = 'elmSizeGetter';\r
219                         style.position = 'absolute';\r
220                         style.left = '0px';\r
221                         style.top = '-9999px';\r
222                         style.visibility = 'hidden';\r
223                         document.body.appendChild( ret);\r
224                         return ret;\r
225                 })(),\r
226                 IMG_SIZE_GETTER = ( function(){\r
227                         var ret = ELM_SIZE_GETTER.cloneNode( true);\r
228                         ret.id = 'imgSizeGetter';\r
229                         document.body.appendChild( ret);\r
230                         return ret;\r
231                 })(),\r
232                 CLEAN_TARGET_ELEMENT = 'script,style,object,applet,embed,iframe,frame,base,bgsound,frameset,listing'.split( ',');\r
233                 \r
234         // cleanCommnetNode();\r
235         function cleanCommnetNode( _targetElm){\r
236                 var _elms = ( _targetElm || document).getElementsByTagName( '*'),\r
237                         _elm,\r
238                         i = 0;\r
239                 while( i < _elms.length){\r
240                         _elm = _elms[ i];\r
241                         if( _elm.nodeType === 8 && _elm.parentNode){\r
242                                 _elm.parentNode.removeChild( _elm);\r
243                         } else {\r
244                                 ++i;\r
245                         }\r
246                 }\r
247         }\r
248         return {\r
249                 extend: function( baseInstance, extend){\r
250                         for( var key in extend){\r
251                                 baseInstance[ key] = extend[ key];\r
252                         }\r
253                         return baseInstance;\r
254                 },\r
255                 cleanCommnetNode: cleanCommnetNode,\r
256                 cleanElement: function( _targetElm){\r
257                         var l = CLEAN_TARGET_ELEMENT.length,\r
258                                 elms, elm, j;\r
259                         for( var i=0; i<l; ++i){\r
260                                 elms = _targetElm.getElementsByTagName( CLEAN_TARGET_ELEMENT[ i]);\r
261                                 if( elms.length > 0){\r
262                                         for( j=0; i<elms.length; ++j){\r
263                                                 elm = elms[ 0];\r
264                                                 elm.parentNode && elm.parentNode.removeChild( elm);\r
265                                         }\r
266                                 }\r
267                         }\r
268                         cleanCommnetNode( _targetElm);\r
269                         if( h2c.isIE === false) return;\r
270                         elms = document.getElementsByName( '*');\r
271                         l = elms.length;\r
272                         for(i=0; i<l; ++i){\r
273                                 elm = elms[ i];\r
274                                 elm.style.filter = '';\r
275                                 elm.style.behavior = '';\r
276                         }\r
277                 },\r
278                 getElementSize: function( _elm){\r
279                         if( !_elm){\r
280                                 return {\r
281                                         width:  0,\r
282                                         height: 0\r
283                                 }\r
284                         }\r
285                         var     parentElm = _elm.parentNode,\r
286                                 prevElm = _elm.previousSibling,\r
287                                 nextElm = _elm.nextSibling,\r
288                                 displayNone = _elm.style.display === 'none';\r
289                         if( displayNone === true) _elm.style.display = '';\r
290                         ELM_SIZE_GETTER.appendChild( _elm);\r
291                         var ret = {\r
292                                 width:          _elm.offsetWidth,\r
293                                 height:         _elm.offsetHeight\r
294                         }\r
295                         if( displayNone === true) _elm.style.display = 'none';\r
296                         if( nextElm){\r
297                                 parentElm.insertBefore( _elm, nextElm);\r
298                         } else          \r
299                         if( prevElm && prevElm.nextSibling){\r
300                                 parentElm.insertBefore( _elm, prevElm.nextSibling);\r
301                         } else {\r
302                                 parentElm && parentElm.appendChild( _elm);\r
303                         }                       \r
304                         return ret;\r
305                 },\r
306                 getImageSize: function( img){\r
307                         var     parentElm = img.parentNode,\r
308                                 prevElm = img.previousSibling,\r
309                                 nextElm = img.nextSibling,\r
310                                 displayNone = img.style.display === 'none';\r
311                         if( displayNone === true) img.style.display = '';\r
312                         IMG_SIZE_GETTER.appendChild( img);\r
313                         var size = getActualDimension( img);\r
314                         IMG_SIZE_GETTER.removeChild( img);\r
315                         if( displayNone === true) img.style.display = 'none';\r
316                         if( nextElm){\r
317                                 parentElm.insertBefore( img, nextElm);\r
318                         } else          \r
319                         if( prevElm && prevElm.nextSibling){\r
320                                 parentElm.insertBefore( img, prevElm.nextSibling);\r
321                         } else {\r
322                                 parentElm && parentElm.appendChild( img);\r
323                         }\r
324                         return size;\r
325                         \r
326                 /* LICENSE: MIT\r
327                  * AUTHOR: uupaa.js@gmail.com\r
328                  */\r
329                         function getActualDimension(image) {\r
330                                 var run, mem, w, h, key = "actual";\r
331                         \r
332                         // for Firefox, Safari, Google Chrome\r
333                                 if ("naturalWidth" in image) {\r
334                                         return {\r
335                                                 width:  image.naturalWidth,\r
336                                                 height: image.naturalHeight\r
337                                         };\r
338                                 }\r
339                         \r
340                                 if ("src" in image) { // HTMLImageElement\r
341                                         if (image[key] && image[key].src === image.src) {\r
342                                                 return image[key];\r
343                                         }\r
344                                         if (document.uniqueID) { // for IE\r
345                                                 run = image.runtimeStyle;\r
346                                                 mem = { w: run.width, h: run.height }; // keep runtimeStyle\r
347                                                 run.width  = "auto"; // override\r
348                                                 run.height = "auto";\r
349                                                 w = image.width;\r
350                                                 h = image.height;\r
351                                                 run.width  = mem.w; // restore\r
352                                                 run.height = mem.h;\r
353                                         } else { // for Opera and Other\r
354                                         /*\r
355                                                 function fn() {\r
356                                                         w = image.width;\r
357                                                         h = image.height;\r
358                                                 }\r
359                                                 mem = { w: image.width, h: image.height }; // keep current style\r
360                                                 image.removeAttribute("width");\r
361                                                 image.addEventListener("DOMAttrModified", fn, false);\r
362                                                 image.removeAttribute("height");\r
363                                                 // call fn\r
364                                                 image.removeEventListener("DOMAttrModified", fn, false);\r
365                                                 image.width  = mem.w; // restore\r
366                                                 image.height = mem.h;\r
367                                         */\r
368                                                 mem = { w: image.width, h: image.height }; // keep current style\r
369                                                 image.removeAttribute("width");\r
370                                                 image.removeAttribute("height");\r
371                                                 w = image.width;\r
372                                                 h = image.height;\r
373                                                 image.width  = mem.w; // restore\r
374                                                 image.height = mem.h;\r
375                                         }\r
376                                         return image[key] = { width: w, height: h, src: image.src }; // bond\r
377                                 }\r
378                                 // HTMLCanvasElement\r
379                                 return { width: image.width, height: image.height };\r
380                         }\r
381                 },\r
382                 loadImage: function( URLorELM, onLoad, onError, delay, timeout){\r
383                         delay = delay || 250;\r
384                         timeout = timeout || 5000;\r
385                         var type = typeof URLorELM,\r
386                                 img, images, src, abstractPath;\r
387                         if( type === 'string'){\r
388                                 src = URLorELM;\r
389                                 // images = [];\r
390                         } else\r
391                         // http://d.hatena.ne.jp/hottolinkblog/20090228/1235823487\r
392                         if( type === 'object' && typeof URLorELM.hspace !== 'undefined' && typeof URLorELM.vspace !== 'undefined'){\r
393                                 img = URLorELM;\r
394                                 images = [ img];\r
395                                 src = img.src;\r
396                         } else {\r
397                                 return;\r
398                         }\r
399                         abstractPath = this.getAbsolutePath( src);\r
400                         \r
401                         loadImage( images, abstractPath,\r
402                                 function( abspath, actualW, actualH){\r
403                                         if( abstractPath !== abspath) return;\r
404                                         onLoad && setTimeout( function(){ // 一度読み込まれた画像は即座にonLoadされてしまうので遅延\r
405                                                 onLoad( src, actualW, actualH);\r
406                                         }, 0);\r
407                                 },\r
408                                 function( abspath){\r
409                                         if( abstractPath !== abspath) return;\r
410                                         onError && setTimeout( function(){\r
411                                                 onError( src);\r
412                                         }, 0);\r
413                                 }, delay, timeout\r
414                         );\r
415                         \r
416                 /*  LICENSE: MIT?\r
417                  *  URL: http://d.hatena.ne.jp/uupaa/20080413/1208067631\r
418                  *  AUTHOR: uupaa.js@gmail.com\r
419                  * \r
420                  *  fixed for ie6-8 by h2c\r
421                  *   new Image -> document.createElement( 'IMG')\r
422                  */\r
423                         function loadImage( images, abspath, onLoad, onError, delay, timeout) {\r
424                                 images = images || document.images;\r
425                                 var img,\r
426                                         i = 0, l = images.length,\r
427                                         tick = 0;\r
428                                 for(; i < l; ++i) {\r
429                                         img = images[i];\r
430                                         if ( img.src === abspath && img.complete) {\r
431                                                 var size = h2c.util.getImageSize( img);\r
432                                                 onLoad( abspath, size.width, size.height);\r
433                                                 return;\r
434                                         }\r
435                                 }\r
436                                 img = document.createElement( 'IMG'); //var img = new Image(); ではieでimgのsizeが取れない、、、removeChildも失敗し、imgSizeGetterにimgが残る\r
437                                 img.finish = false;\r
438                                 img.onabort = img.onerror = function() {\r
439                                         if (img.finish) { return; }\r
440                                         img.finish = true;\r
441                                         onError(abspath);\r
442                                         img.onload = img.onabort = img.onerror = "";\r
443                                 };\r
444                                 img.onload  = function() {\r
445                                         img.finish = true;\r
446                                         if (window.opera && !img.complete) {\r
447                                                 onError(abspath);\r
448                                                 img.onload = img.onabort = img.onerror = "";\r
449                                                 return;\r
450                                         }\r
451                                         var size = h2c.util.getImageSize( img);\r
452                                         onLoad( abspath, size.width, size.height);\r
453                                         img.onload = img.onabort = img.onerror = "";\r
454                                         //img = void 0;\r
455                                 };\r
456                                 img.src = abspath;\r
457                                 if (!img.finish && timeout) {\r
458                                         setTimeout(function() {\r
459                                                 if (img.finish) { return; }\r
460                                                 if (img.complete) {\r
461                                                         img.finish = true;\r
462                                                         if (img.width) { return; }\r
463                                                         onError(abspath);\r
464                                                         img.onload = img.onabort = img.onerror = "";\r
465                                                         return;\r
466                                                 }\r
467                                                 if ((tick += delay) > timeout) {\r
468                                                         img.finish = true;\r
469                                                         onError(abspath);\r
470                                                         img.onload = img.onabort = img.onerror = "";\r
471                                                         return;\r
472                                                 }\r
473                                                 setTimeout(arguments.callee, delay);\r
474                                         }, 0);\r
475                                 }\r
476                         }\r
477                 },\r
478                 getAbsolutePath: function( path) {\r
479                         var e = document.createElement("div");\r
480                         e.innerHTML = '<a href=\"' + path + '\" />';\r
481                         return e.firstChild.href;\r
482                 }\r
483         }\r
484 })();\r
485 \r
486 /*\r
487  * window resize event, overlay と currentなviewに流す\r
488  * view modeの保持\r
489  *       editor, overlay, comic-viewer, image-explorer\r
490  * fadeIn, faseOut\r
491  */\r
492 h2c.view = ( function(){\r
493         var jqWindow,\r
494                 funcArray,\r
495                 HOME_ID = 'home',\r
496                 elmCurrent,\r
497                 viewID = ( function(){\r
498                         var _viewID = h2c.URL_PARAMS.view || HOME_ID,\r
499                                 _elmView = document.getElementById( _viewID),\r
500                                 _elmHome = document.getElementById( HOME_ID);\r
501                         if( _elmView){\r
502                                 _elmHome.style.display = '';\r
503                                 _elmView.style.display = 'block';\r
504                                 elmCurrent = _elmView;\r
505                                 return _viewID;\r
506                         }\r
507                         elmCurrent = _elmHome;\r
508                         return HOME_ID;\r
509                 })(),\r
510                 currentView;\r
511 \r
512         function onWindowResize(){\r
513                 var _fn,\r
514                         l = funcArray.length,\r
515                         w = jqWindow.width(),\r
516                         h = jqWindow.height();\r
517                 for( var i=0; i<l; ++i){\r
518                         _fn = funcArray[ i];\r
519                         _fn.onWindowResize && _fn.onWindowResize( w, h);\r
520                 }\r
521         }\r
522         return {\r
523                 init: function( _funcArray){\r
524                         funcArray = _funcArray;\r
525                         jqWindow = h2c.jqWindow();\r
526                         jqWindow.resize( onWindowResize);\r
527                         currentView = h2c[ viewID];\r
528                         setTimeout( onWindowResize, 100);\r
529                         \r
530                         delete h2c.view.init;\r
531                 },\r
532                 show: function( _view){\r
533                         for( var key in h2c){\r
534                                 if( h2c[ key] === _view){\r
535                                         var elm = document.getElementById( key);\r
536                                         if( currentView !== _view && elm){\r
537                                                 this.currentID = viewID = key;\r
538                                                 currentView = _view;\r
539                                                 elmCurrent.style.display = '';\r
540                                                 elm.style.display = 'block';\r
541                                                 elmCurrent = elm;\r
542                                         }\r
543                                         return;\r
544                                 }\r
545                         }\r
546                         alert( 'fault!!');\r
547                 },\r
548                 currentID: viewID,\r
549                 HOME: HOME_ID,\r
550                 COMICS: 'comic-list',\r
551                 IMAGES: 'image-list',\r
552                 SETTING: 'setting',\r
553                 EDITOR: 'editor',\r
554                 OVERLAY: 'overlay'\r
555         }\r
556 })();\r
557 \r
558 h2c.overlay = ( function(){\r
559         var SHADOW_OPACITY = 0.5,\r
560                 jqBody, jqConteiner, jqShadow, jqCloseButton,\r
561                 currentOverlay = null,\r
562                 visible = false;\r
563         \r
564         function close(){\r
565                 currentOverlay && currentOverlay.onClose && currentOverlay.onClose();\r
566                 h2c.overlay.hide();             \r
567         }\r
568         return {\r
569                 init: function(){\r
570                         jqBody = h2c.jqBody();\r
571                         jqConteiner = $( '#overlay-container');\r
572                         jqShadow = $( '#overlay-shadow');\r
573                         jqCloseButton = $( '#overlay-close-button').click( function( e){\r
574                                 close();\r
575                                 e.preventDefault();\r
576                                 return false;\r
577                         });\r
578                         \r
579                         h2c.key.addKeyDownEvent( h2c.view.OVERLAY, 27, false, false, close); // 27.esc\r
580                         \r
581                         delete h2c.overlay.init;\r
582                 },\r
583                 show: function( _currentOverlay){\r
584                         if( visible === true && currentOverlay === _currentOverlay) return;\r
585                         jqConteiner.stop().css( {\r
586                                 filter:         '',\r
587                                 opacity:        ''\r
588                         }).fadeIn();\r
589                         this.visible = visible = true;\r
590                         currentOverlay = _currentOverlay;\r
591                         this.currentID = _currentOverlay.ID;\r
592                         jqCloseButton.toggle( !!_currentOverlay.onClose);\r
593                 },\r
594                 hide: function(){\r
595                         currentOverlay = null;\r
596                         if( visible === false) return;\r
597                         jqConteiner.stop().css( {\r
598                                 filter:         '',\r
599                                 opacity:        ''\r
600                         }).fadeOut();\r
601                         this.visible = visible = false;\r
602                         this.currentID = null;\r
603                 },\r
604                 visible: visible,\r
605                 currentID: null,\r
606                 onWindowResize: function( _windowW, _windowH){\r
607                         jqConteiner.css( { height:      _windowH});\r
608                         jqShadow.css( { height: _windowH});\r
609                         currentOverlay && currentOverlay.onWindowResize && setTimeout( function(){ // 先にeditorのcanvasを確定する。\r
610                                 currentOverlay.onWindowResize( _windowW, _windowH);\r
611                         }, 0);\r
612                 }\r
613         }\r
614 })();\r
615 \r
616 /* ----------------------------------------\r
617  * KEY\r
618  * \r
619  *  - EDITABLE_TEXT_CONTROL\r
620  *    - EditableTextClass\r
621  *      .update: function,\r
622  *      .show: function,\r
623  *      .hide: function,\r
624  *      .start: function,\r
625  *      .finish: finish,\r
626  *      .enabled: function,\r
627  *      .index: function,\r
628  *      .instance: function\r
629  * \r
630  *    .SHIFT_DOWN_EVENT:        'shiftDown',\r
631  *    .SHIFT_UP_EVENT:          'shiftUp',\r
632  *    .CTRL_DOWN_EVENT:         'ctrlDown',\r
633  *    .CTRL_UP_EVENT:           'ctrlUp',\r
634  *    .SPACE_DOWN_EVENT:        'spaceDown',\r
635  *    .SPACE_UP_EVENT:          'spaceUp',\r
636  *    .init:                            function,\r
637  *    .addKeyDownEvent:                 function,\r
638  *    .keyEventDispatcher:      function,\r
639  *    .createEditableText:      function,\r
640  * \r
641  * ショートカットキーの監視とテキスト入力(input, textarea)、チェックボックスを管理する。\r
642  * キー入力はdocumentで受けて、テキスト編集中(input, textarea)はそちらにキーイベント流す。\r
643  * \r
644  */\r
645 h2c.key = ( function(){\r
646         var log,\r
647                 jqWindow,\r
648                 keyOperationChatcher,\r
649                 KEYEVENT_ARRAY = [],\r
650                 shiftEnabled = false,\r
651                 ctrlEnabled = false;\r
652         \r
653         var EDITABLE_TEXT_CONTROL = ( function(){\r
654                 var     EDITABLE_TEXT_TABLE = {},\r
655                         currentText = null;\r
656 \r
657                 var EditableTextClass = function( WRAPPER_ELM, ON_UPDATE_FUNCTION, GROUP_ID){\r
658                         var ELM = WRAPPER_ELM.children( '.editable-value').eq( 0),\r
659                                 value = ELM.html(),\r
660                                 jqInput,\r
661                                 index = EDITABLE_TEXT_TABLE[ GROUP_ID].length,\r
662                                 instance,\r
663                                 enabled = true,\r
664                                 A = $( '<a href="#" onclick="return false;"></a>').html( value).click( function(e){\r
665                                         instance = instance || EDITABLE_TEXT_TABLE[ GROUP_ID][ index];\r
666                                         EDITABLE_TEXT_CONTROL.start( instance);                                                         \r
667                                         A.hide();\r
668                                         jqInput = $( '<input type="text"/>').val( value)//.keydown( finish).keypress( finish);\r
669                                         ELM.append( jqInput);\r
670                                         jqInput.focus().select();\r
671                                         e.preventDefault();\r
672                                         return false;\r
673                                 });\r
674                         ELM.addClass( 'editable-text').html( A);\r
675                         \r
676                         function finish(e){\r
677                                 if(e){\r
678                                         var keyCode = e.keyCode;\r
679                                         if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true){ // 13.return 27.esc 9.tab 18.alt\r
680                                                 _finish( keyCode !== 27 ? jqInput.val() : value);\r
681                                                 keyCode === 9 && GROUP_ID && EDITABLE_TEXT_CONTROL.tabShift( GROUP_ID, index, e.shiftKey === true ? -1 : 1);\r
682                                         }\r
683                                 } else {\r
684                                         _finish( jqInput.val());\r
685                                 }\r
686                                 function _finish( VALUE_NEW){\r
687                                         value = VALUE_NEW;\r
688                                         A.html( VALUE_NEW).show();\r
689                                         jqInput.remove();\r
690                                         jqInput = null;\r
691                                         ON_UPDATE_FUNCTION && VALUE_NEW !== value && ON_UPDATE_FUNCTION( VALUE_NEW, value);\r
692                                         EDITABLE_TEXT_CONTROL.finish( instance);\r
693                                 }\r
694                         }\r
695                         return {\r
696                                 update: function( _value){\r
697                                         value = _value !== undefined ? _value : value;\r
698                                         A.html( value);\r
699                                         jqInput && jqInput.val( value);\r
700                                         currentText === instance && finish();\r
701                                 },\r
702                                 show: function(){\r
703                                         enabled === false && WRAPPER_ELM.show();\r
704                                         enabled= true;\r
705                                 },\r
706                                 hide: function(){\r
707                                         enabled === true && WRAPPER_ELM.hide();\r
708                                         enabled = false;\r
709                                 },\r
710                                 start: function(){\r
711                                         !jqInput && A.click();\r
712                                 },\r
713                                 finish: finish,\r
714                                 enabled: function(){\r
715                                         return enabled;\r
716                                 }\r
717                         }\r
718                 }\r
719                 var CheckboxClass = function( WRAPPER_ELM, ON_UPDATE_FUNCTION, GROUP_ID){\r
720                         var ELM = WRAPPER_ELM.children( '.checkbox-value').eq( 0),\r
721                                 value = ELM.html(),\r
722                                 jqInput,\r
723                                 index = EDITABLE_TEXT_TABLE[ GROUP_ID].length,\r
724                                 instance,\r
725                                 enabled = true,\r
726                                 A = $( '<a href="#" onclick="return false;"></a>').html( value).click( function(e){\r
727                                         instance = instance || EDITABLE_TEXT_TABLE[ GROUP_ID][ index];\r
728                                         EDITABLE_TEXT_CONTROL.start( instance);                                                         \r
729                                         A.hide();\r
730                                         jqInput = $( '<input type="text"/>').val( value)//.keydown( finish).keypress( finish);\r
731                                         ELM.append( jqInput);\r
732                                         jqInput.focus().select();\r
733                                         e.preventDefault();\r
734                                         return false;\r
735                                 });\r
736                         ELM.addClass( 'editable-text').html( A);\r
737                         \r
738                         function finish(e){\r
739                                 if(e){\r
740                                         var keyCode = e.keyCode;\r
741                                         if( keyCode === 13 || keyCode === 27 || keyCode === 9 || keyCode === 18 || e.altKey === true){ // 13.return 27.esc 9.tab 18.alt\r
742                                                 _finish( keyCode !== 27 ? jqInput.val() : value);\r
743                                                 keyCode === 9 && GROUP_ID && EDITABLE_TEXT_CONTROL.tabShift( GROUP_ID, index, e.shiftKey === true ? -1 : 1);\r
744                                         }\r
745                                 } else {\r
746                                         _finish( jqInput.val());\r
747                                 }\r
748                                 function _finish( VALUE_NEW){\r
749                                         value = VALUE_NEW;\r
750                                         A.html( VALUE_NEW).show();\r
751                                         jqInput.remove();\r
752                                         jqInput = null;\r
753                                         ON_UPDATE_FUNCTION && VALUE_NEW !== value && ON_UPDATE_FUNCTION( VALUE_NEW, value);\r
754                                         EDITABLE_TEXT_CONTROL.finish( instance);\r
755                                 }\r
756                         }\r
757                         return {\r
758                                 update: function( _value){\r
759                                         value = _value !== undefined ? _value : value;\r
760                                         A.html( value);\r
761                                         jqInput && jqInput.val( value);\r
762                                         currentText === instance && finish();\r
763                                 },\r
764                                 show: function(){\r
765                                         enabled === false && WRAPPER_ELM.show();\r
766                                         enabled= true;\r
767                                 },\r
768                                 hide: function(){\r
769                                         enabled === true && WRAPPER_ELM.hide();\r
770                                         enabled = false;\r
771                                 },\r
772                                 start: function(){\r
773                                         !jqInput && A.click();\r
774                                 },\r
775                                 finish: finish,\r
776                                 enabled: function(){\r
777                                         return enabled;\r
778                                 }\r
779                         }\r
780                 }\r
781                 return {\r
782                         createEditableText: function( ELM, ON_UPDATE_FUNCTION, GROUP_ID){\r
783                                 if( GROUP_ID && !EDITABLE_TEXT_TABLE[ GROUP_ID]) EDITABLE_TEXT_TABLE[ GROUP_ID] = [];\r
784                                 var ret = EditableTextClass.apply( {}, [ ELM, ON_UPDATE_FUNCTION, GROUP_ID]);\r
785                                 GROUP_ID && EDITABLE_TEXT_TABLE[ GROUP_ID].push( ret);\r
786                                 return ret;\r
787                         },\r
788                         createCheckbox: function( ELM, ON_UPDATE_FUNCTION, GROUP_ID){\r
789                                 \r
790                         },\r
791                         start: function( _currentText){\r
792                                 currentText !== _currentText && currentText && currentText.finish();\r
793                                 currentText = _currentText;\r
794                         },\r
795                         finish: function( _currentText){\r
796                                 if( currentText !== _currentText) return;\r
797                                 currentText = null \r
798                         },\r
799                         keyEventRellay: function( e){\r
800                                 currentText && currentText.finish( e);\r
801                                 return !!currentText;\r
802                         },\r
803                         tabShift: function( _groupID, _index, _way){\r
804                                 var GROUP_ARRAY = EDITABLE_TEXT_TABLE[ _groupID] || [],\r
805                                         l = GROUP_ARRAY.length,\r
806                                         i = _index +_way;\r
807                                 if( l < 2) return;\r
808                                 while( i !== _index){\r
809                                         i = i < 0 ?\r
810                                                 l -1 :\r
811                                                 i === l ? 0 : i; // 0 < i < l\r
812                                         if( GROUP_ARRAY[ i].enabled() === true) break;\r
813                                         i += _way;\r
814                                 }\r
815                                 if( i === _index) return;\r
816                                 setTimeout( function(){ GROUP_ARRAY[ i].start();}, 0);\r
817                         }\r
818                 }\r
819         })();\r
820         \r
821         function keyHit( e){\r
822                 log.html( [ e.keyCode, e.shiftKey, e.ctrlKey, e.altKey, e.type].join( ','));\r
823                 //keyOperationChatcher.val( '');\r
824                 var cancel = false,\r
825                         callback = ( function(){\r
826                                 var type = e.type;\r
827                                 if( type === 'keypress') return 'keydown';\r
828                                 return type;\r
829                         })(),\r
830                         key = e.keyCode,\r
831                         overlayEnabled = h2c.overlay.visible === true,\r
832                         currentViewID = overlayEnabled === true ? h2c.overlay.currentID : h2c.view.currentID;\r
833                 if( callback === 'keyup' || EDITABLE_TEXT_CONTROL.keyEventRellay( e) === false){\r
834                         var shift = e.shiftKey,\r
835                                 ctrl = e.ctrlKey,\r
836                                 l = KEYEVENT_ARRAY.length,\r
837                                 d;\r
838                         \r
839                         shiftEnabled = callback !== 'keyup' ?\r
840                                                         e.shiftKey :\r
841                                                         key !== 16 ? shiftEnabled : false;\r
842                         ctrlEnabled = callback !== 'keyup' ?\r
843                                                         e.ctrlKey :\r
844                                                         key !== 17 ? ctrlEnabled : false;;                      \r
845 \r
846                         for( var i=0; i<l; i++){\r
847                                 d = KEYEVENT_ARRAY[ i];\r
848                                 if( (\r
849                                                 d.viewID === currentViewID ||\r
850                                                         ( overlayEnabled === true && d.viewID === h2c.view.OVERLAY)\r
851                                         ) &&\r
852                                         d.keyCode === key &&\r
853                                         ( d.shift === undefined || d.shift === shift) &&\r
854                                         ( d.ctrl === undefined || d.ctrl === ctrl)\r
855                                 ){\r
856                                         ( function( func, e){\r
857                                                 func && setTimeout( function(){\r
858                                                         func( e);\r
859                                                         func = e = null;\r
860                                                 }, 0);\r
861                                         })( d[callback], e);\r
862                                         cancel = true;\r
863                                 }\r
864                         }\r
865                 }\r
866                 if( cancel === true || key === 18 || key === 9 || key === 27 || e.altKey === true){ // 13.enter 18.esc 9.tab 27.esc   || ( key === 13 && overlayEnabled === false)\r
867                         e.preventDefault();\r
868                 e.keyCode = 0;\r
869                 e.cancelBubble = true;\r
870                 e.returnValue = false;\r
871                         return false;\r
872                 }\r
873         }\r
874 \r
875         return {\r
876                 init: function(){\r
877                         log = $( '#key-event-log').html( 'ready');\r
878 \r
879                         jqWindow = h2c.jqWindow().focus();\r
880                         keyOperationChatcher = h2c.jqDocument()\r
881                                 .keydown( keyHit)\r
882                                 .keyup( keyHit)\r
883                                 .mouseenter( function(){\r
884                                         jqWindow.focus();\r
885                                 });\r
886                         h2c.isIE === true && h2c.ieRenderingVersion < 8 && keyOperationChatcher.keypress( function( e){\r
887                                 var key = e.keyCode;\r
888                                 if( key === 13 || key === 27){\r
889                                         keyHit( e);\r
890                                         return false;\r
891                                 }\r
892                         });\r
893 \r
894                         delete h2c.key.init;\r
895                 },\r
896                 addKeyDownEvent: function( _viewID, _keyCode, _shift, _ctrl, _callbackFunction){\r
897                         KEYEVENT_ARRAY.push( {\r
898                                 viewID:                 _viewID,\r
899                                 keyCode:                _keyCode,\r
900                                 shift:                  _shift,\r
901                                 ctrl:                   _ctrl,\r
902                                 keydown:                _callbackFunction\r
903                         });\r
904                 },\r
905                 addKeyUpdateEvent: function( _viewID, _keyCode, _shift, _ctrl, _callbackFunction){\r
906                         KEYEVENT_ARRAY.push( {\r
907                                 viewID:         _viewID,\r
908                                 keyCode:        _keyCode,\r
909                                 shift:          _shift,\r
910                                 ctrl:           _ctrl,\r
911                                 keydown:        _callbackFunction,\r
912                                 keyup:          _callbackFunction\r
913                         });\r
914                 },\r
915                 addCursorEvent: function( _viewID, _shift, _ctrl, _callbackFunction){\r
916                         \r
917                 },\r
918                 keyEventDispatcher: function(){\r
919                         return keyOperationChatcher;\r
920                 },\r
921                 createEditableText: EDITABLE_TEXT_CONTROL.createEditableText,\r
922                 createCheckbox: EDITABLE_TEXT_CONTROL.createCheckbox,\r
923                 shiftEnabled: function(){\r
924                         return shiftEnabled;\r
925                 },\r
926                 ctrlEnabled: function(){\r
927                         return ctrlEnabled;\r
928                 }\r
929         }\r
930 })();\r
931 \r
932 /* ----------------------------------------\r
933  * Vector Support\r
934  * \r
935  *              __________\r
936  *             /          \\r
937  *            /            \\r
938  *            |,startX,Y    |\r
939  * tailX,Y - <              |\r
940  *            |'endX,Y      |\r
941  *            \            /\r
942  *                 \__________/\r
943  * \r
944  * SVG\r
945  * -----------------------\r
946  * ie9, other modern browser\r
947  * \r
948  * XML\r
949  * -----------------------\r
950  * ie5.5-8\r
951  * \r
952  * 内部の角度計算は radian で統一したい。\r
953  * 当初 vectorEnabled = true で一度書いてみる。\r
954  * 駄目なら、代替のイメージのsrcの用意もここで担当。\r
955  * 閲覧と編集両方で使う。\r
956  * \r
957  */\r
958 h2c.balloon = ( function() {\r
959         var MIN_BALLOON_WIDTH = 30,\r
960                 MIN_BALLOON_HEIGHT = 30,\r
961                 TAIL_WIDTH = 6,\r
962                 TAIL_HEIGHT = 10,\r
963                 STROKE_WIDTH = 1.2,\r
964                 PADDING_TOP = TAIL_HEIGHT,\r
965                 PADDING_LEFT = TAIL_HEIGHT,\r
966                 ACCURACY = 1, // 有効少数桁        \r
967                 IS_VML = h2c.isIE === true && h2c.ieVersion < 9,\r
968                 ELM_BALLOON_ORIGIN = ( function(){\r
969                         var ret;\r
970                         try {\r
971                                 if( IS_VML === true){\r
972                                         ret = document.createElement( 'DIV');\r
973                                         var shape = document.createElement( 'v:shape');\r
974                                         shape.coordorigin = "0,0";\r
975                                         shape.strokecolor = "black";\r
976                                         shape.strokeweight = STROKE_WIDTH;\r
977                                         shape.fillcolor = "white";\r
978                                         ret.appendChild( shape);\r
979                                 } else {\r
980                                         var kSVGNS = 'http://www.w3.org/2000/svg';\r
981                                         ret = document.createElementNS( kSVGNS, 'svg');\r
982                                         var path = document.createElementNS( kSVGNS, 'path');\r
983                                         path.setAttribute( 'fill', "white");\r
984                                         path.setAttribute( 'stroke', "black");\r
985                                         path.setAttribute( 'strokeWidth', STROKE_WIDTH);\r
986                                         ret.appendChild( path);\r
987                                 }\r
988                                 return ret;     \r
989                         } catch( e){\r
990                                 return null;\r
991                         }\r
992                 })(),\r
993                 NUM_BALLOON_IMAGE = 24,\r
994                 vectorEnabled = ELM_BALLOON_ORIGIN !== null && h2c.URL_PARAMS.vector !== false;\r
995         if( IS_VML === true && h2c.VML === false) vectorEnabled = false;\r
996 \r
997         var XBROWSER_BALLOON_CLASS = function( w, h, a){\r
998                 var balloonElm = vectorEnabled === true ? ELM_BALLOON_ORIGIN.cloneNode( true) : document.createElement( 'IMG'), // h2c.imageに変更\r
999                         path = balloonElm.getElementsByTagName( 'path')[ 0],\r
1000                         shape = balloonElm.getElementsByTagName( 'shape')[ 0],\r
1001                         cos = Math.cos, sin = Math.sin,\r
1002                         abs = Math.abs, pow = Math.pow,\r
1003                         round = Math.round,\r
1004                         floor = Math.floor,\r
1005                         TARGET = TAIL_WIDTH * TAIL_WIDTH,\r
1006                         DEG_TO_RAD = Math.PI / 180,\r
1007                         l = ',';\r
1008                 \r
1009                 draw( a, w, h);\r
1010                 \r
1011                 function draw( _a, _w, _h){\r
1012                         a = _a !== undefined ? _a : a;\r
1013                         w = _w !== undefined ? _w -PADDING_TOP *2 : w;\r
1014                         h = _h !== undefined ? _h -PADDING_LEFT *2 : h;\r
1015 \r
1016                         if( vectorEnabled === false){\r
1017                                 balloonElm.setAttribute( 'src', balloonUrlBuilder( a));\r
1018                                 return;\r
1019                         }\r
1020                         \r
1021                         var rx = w /2,\r
1022                                 ry = h /2,\r
1023                                 tailRad = a * DEG_TO_RAD,\r
1024                                 tailX = rx +( rx +TAIL_HEIGHT) * cos( tailRad),\r
1025                                 tailY = ry +( ry +TAIL_HEIGHT) * sin( tailRad),\r
1026                                 startX, startY, endX, endY;\r
1027                 /*\r
1028                  * tailの太さをTAIL_WIDTHに一致させるため、角度を絞りつつ計算\r
1029                  */\r
1030                         var startRad, endRad,\r
1031                                 _startX, _startY, _endX, _endY,\r
1032                                 tailDeg = 0, d;\r
1033                         \r
1034                         for( var i = 45; i > 0.01; i /= 2){\r
1035                                 d = ( tailDeg +i) /2;\r
1036                                 startRad = ( a +d) * DEG_TO_RAD;\r
1037                                 endRad = ( a -d) * DEG_TO_RAD;\r
1038                                 \r
1039                                 _startX = rx +cos( startRad) *rx;\r
1040                                 _startY = ry +sin( startRad) *ry;\r
1041                                 _endX = rx +cos( endRad) *rx;\r
1042                                 _endY = ry +sin( endRad) *ry;   //円弧上のY位置=円中心Y+sin(角度×PI÷180)×円半径\r
1043                                         \r
1044                                 if( pow( ( _startX -_endX), 2) + pow( ( _startY -_endY), 2) < TARGET){\r
1045                                         tailDeg += i;\r
1046                                         startX = _startX;\r
1047                                         startY = _startY;\r
1048                                         endX = _endX;\r
1049                                         endY = _endY;                                           \r
1050                                 }\r
1051                         }\r
1052 \r
1053                 /*\r
1054                  * \r
1055                  */                     \r
1056                         if( IS_VML === true){\r
1057                                 var _tailX = tailX *10,\r
1058                                         _tailY = tailY *10,\r
1059                                         __startX = startX *10,\r
1060                                         __startY = startY *10,\r
1061                                         __endX = endX *10,\r
1062                                         __endY = endY *10,\r
1063                                         __w = w *10,\r
1064                                         __h = h *10;\r
1065                                 \r
1066                                 shape.style.width = w +'px';\r
1067                                 shape.style.height = h +'px';\r
1068                                 shape.coordsize = [ __w, __h].join( l);\r
1069                                 shape.path = [\r
1070                                         ' ar ', 0, l, 0, l, __w, l, __h, l,\r
1071                                         round( __endX), l, round( __endY), l,\r
1072                                         round( __startX), l, round( __startY),\r
1073                                         ' l ', round( _tailX), l, round( _tailY),\r
1074                                         ' x e'\r
1075                                 ].join( '');\r
1076 \r
1077                                 balloonElm.style.marginTop =  _tailY < 0 ? floor( ( 60 +_tailY) /10) : 10;\r
1078                                 balloonElm.style.marginLeft = _tailX < 0 ? floor( ( 60 +_tailX) /10) : 10;\r
1079                         } else {\r
1080                                 balloonElm.setAttribute( 'width', w +PADDING_LEFT *2);\r
1081                                 balloonElm.setAttribute( 'height', h +PADDING_TOP *2);\r
1082                                 path.setAttribute( 'd', [\r
1083                                         'M', cround( tailX + PADDING_LEFT), l, cround( tailY +PADDING_TOP),\r
1084                                         'L', cround( startX +PADDING_LEFT), l, cround( startY +PADDING_TOP),\r
1085                                         'A', rx, l, ry,\r
1086                                         '0 1 1',                        // flag\r
1087                                         cround( endX +PADDING_LEFT), l, cround( endY +PADDING_TOP),\r
1088                                         'z'\r
1089                                 ].join( ' '));\r
1090                         }\r
1091                         function cround( v, r){\r
1092                                 r = r || ACCURACY;\r
1093                                 return round( v *pow( 10.0, r)) /pow( 10.0, r);\r
1094                         }\r
1095                 }\r
1096                 \r
1097                 function balloonUrlBuilder( _a){\r
1098                         var d = 360 /NUM_BALLOON_IMAGE;\r
1099                         _a += 90 +d /2;\r
1100                         return [ 'balloon\/_w', _a < 360 -d /2 ? floor( _a /d) : 0, '.gif'].join( '');\r
1101                 }\r
1102                 return {\r
1103                         elm: balloonElm,\r
1104                         resize: draw,\r
1105                         angle: function( _a){\r
1106                                 _a !== undefined && _a !== a &&\r
1107                                         vectorEnabled === false ? balloonUrlBuilder( _a) : draw( _a);\r
1108                                 return a;\r
1109                         },\r
1110                         type: function( _type){\r
1111                                 //draw( _a);\r
1112                         },\r
1113                         getURL: function(){\r
1114                                 return balloonUrlBuilder( a);\r
1115                         },\r
1116                         destroy: function(){\r
1117                                 balloonElm.parentNode && balloonElm.parentNode.removeChild( balloonElm);\r
1118                                 balloonElm = null;\r
1119                                 delete this.destroy;\r
1120                         }\r
1121                 }\r
1122         };\r
1123         \r
1124         IS_VML === false && vectorEnabled === true && ( function(){\r
1125                 var detect = XBROWSER_BALLOON_CLASS.apply( {}, [ 100, 100, 0]),\r
1126                         size = h2c.util.getElementSize( detect.elm);\r
1127                 vectorEnabled = size.width !== 0 && size.height !== 0;\r
1128                 detect.destroy();\r
1129                 detect = size = null;\r
1130         })();\r
1131 \r
1132         return {\r
1133                 init: function(){\r
1134                         delete h2c.balloon.init;\r
1135                 },\r
1136             enabled: function() {\r
1137                 return vectorEnabled;\r
1138             },\r
1139                 VML: IS_VML === true && vectorEnabled === true,\r
1140             createBalloon: function( _w, _h, _a){\r
1141                 return XBROWSER_BALLOON_CLASS.apply( {}, [ _w, _h, _a]);\r
1142             },\r
1143                 TYPE_NONE:                              0,\r
1144                 TYPE_SPEACH_BALLOON:    1,\r
1145                 TYPE_THINKING:                  2,\r
1146                 TYPE_BOM:                               3,\r
1147                 TYPE_BLACK_BOX:                 4,\r
1148                 TYPE_BLUE_BOX:                  5\r
1149         }\r
1150 })();\r
1151 \r
1152 /* ----------------------------------------\r
1153  *  h2c.image\r
1154  *  \r
1155  *   xBackendな画像反転、画像描画機能。\r
1156  *   \r
1157  *   画像の反転\r
1158  *     - css3\r
1159  *     - ActiveX (ie)\r
1160  *     - VML (ie)\r
1161  *     - canvas ??\r
1162  *     - flash(lite)\r
1163  *     - silverlight\r
1164  *     - pettan server\r
1165  *   \r
1166  *   png画像の表示(アルファpngをサポートしないie6以下のため)\r
1167  *     - ActiveX\r
1168  *     - VML\r
1169  *     - flash(lite)\r
1170  *     - silverlight\r
1171  *     \r
1172  *     -moz-transform:scale( -1, -1);\r
1173  */\r
1174 h2c.image = ( function(){\r
1175         var REG_PNG = /\.png?/i,\r
1176                 IS_CSS3 = 0,\r
1177                 IS_VML = 1,\r
1178                 IS_ACTIVEX = 2,\r
1179                 IS_CANVAS = 3,\r
1180                 IS_FLASH = 4,\r
1181                 IS_SILVERLIGHT = 5,\r
1182                 IS_SERVER = 6,\r
1183                 IS_ACTIVEX_SERVER = 7,\r
1184                 BACKEND = ( function(){\r
1185                         if( h2c.DEBUG === true && h2c.URL_PARAMS.rimg){\r
1186                                 var rimg = h2c.URL_PARAMS.rimg.toLowerCase();\r
1187                                 if( rimg === 'css3') return IS_CSS3;\r
1188                                 if( rimg === 'activex') return IS_ACTIVEX;\r
1189                                 if( rimg === 'vml') return IS_VML;\r
1190                         }\r
1191                         if( h2c.isIE === false || h2c.ieVersion >= 9) return IS_CSS3; // 不十分!\r
1192                         if( h2c.VML === true) return IS_VML;\r
1193                         if( h2c.ACTIVEX === true) return IS_ACTIVEX;\r
1194                         if( h2c.FLASH === true) return IS_FLASH;\r
1195                         if( h2c.SILVERLIGHT === true) return IS_SILVERLIGHT;\r
1196                         return IS_SERVER;\r
1197                 })(),\r
1198                 PNG_FIX = h2c.isIE === true && h2c.ieVersion <= 6,\r
1199                 BACKEND_WHEN_PNG = PNG_FIX === false ? BACKEND : ( function(){\r
1200                         if( h2c.balloon.VML === true) return IS_VML;\r
1201                         if( h2c.FLASH === true) return IS_FLASH;\r
1202                         if( h2c.SILVERLIGHT === true) return IS_SILVERLIGHT;\r
1203                         if( h2c.ACTIVEX === true) return IS_ACTIVEX_SERVER;\r
1204                         return IS_SERVER;\r
1205                 })();\r
1206         \r
1207         var XBackendReversibleImageClass = ( function(){\r
1208                 var CLASS_NAME = 'reversible-image-container',\r
1209                         CLASS_NAME_LOADING = CLASS_NAME + ' loading',\r
1210                         CLASS_NAME_ERROR = CLASS_NAME +' error',\r
1211                         RETRY_DELAY = 5000;\r
1212                         NUM_RETRY = 3;\r
1213                 \r
1214                 var css3Image = function( url, w, h, onLoadCallback){\r
1215                         var elmWrap = document.createElement( 'div'),\r
1216                                 elmImg,\r
1217                                 loaded = false,\r
1218                                 retryTimer = null;\r
1219                         elmWrap.className = CLASS_NAME_LOADING;\r
1220                         h2c.util.loadImage( url, onLoad, onError, 100, 10000);\r
1221                         function onLoad( _url, _actualW, _actualH){\r
1222                                 if( elmWrap === null) return;\r
1223                                 elmImg = new Image;\r
1224                                 /*\r
1225                                  * createElement 直後に append しないと、ie(ActiveX)で img が正しく表示されない.\r
1226                                  */\r
1227                                 elmWrap.appendChild( elmImg);\r
1228                                 elmImg.setAttribute( 'src', url);\r
1229                                 elmWrap.className = CLASS_NAME;\r
1230                                 onLoadCallback && onLoadCallback( _url, _actualW, _actualH);\r
1231                                 onLoadCallback = null;\r
1232                                 loaded = true;\r
1233                                 resize( w, h);\r
1234                         }\r
1235                         function onError( _url){\r
1236                                 if( elmWrap === null) return;\r
1237                                 elmWrap.className = CLASS_NAME_ERROR;\r
1238                                 retryTimer = setTimeout( function(){\r
1239                                         elmWrap.className = CLASS_NAME_LOADING;\r
1240                                         h2c.util.loadImage( url, onLoad, onError, 100, 10000);\r
1241                                 }, RETRY_DELAY);\r
1242                         }\r
1243                         function resize( _w, _h){\r
1244                                 w = _w !== undefined ? _w : w;\r
1245                                 h = _h !== undefined ? _h : h;\r
1246                                 if( loaded === false) return;\r
1247                                 elmImg.className = w < 0 || h < 0 ? ( 'img-flip-' + ( w < 0 && h < 0 ? 'vh' : ( w < 0 ? 'v' : 'h'))) : '';\r
1248                         }\r
1249                         return {\r
1250                                 elm : elmWrap,\r
1251                                 resize: resize,\r
1252                                 destroy: function(){\r
1253                                         loaded === true && elmWrap.removeChild( elmImg);\r
1254                                         retryTimer !== null && clearTimeout( retryTimer);\r
1255                                         elmWrap = vmlImg = onLoadCallback = retryTimer = null;\r
1256                                         elmWrap = elmImg = onLoadCallback = null;\r
1257                                         delete this.destroy;\r
1258                                 }\r
1259                         }\r
1260                 }\r
1261                 var activexImage = css3Image;\r
1262                 var vmlImage = function( url, w, h, onLoadCallback){\r
1263                         var elmWrap = document.createElement( 'div'),\r
1264                                 vmlImg,\r
1265                                 loaded = false,\r
1266                                 retryTimer = null;\r
1267                         elmWrap.className = CLASS_NAME_LOADING;\r
1268                         h2c.util.loadImage( url, onLoad, onError, 100, 10000);\r
1269                         function onLoad( _url, _actualW, _actualH){\r
1270                                 if( elmWrap === null) return;\r
1271                                 elmWrap.className = CLASS_NAME;\r
1272                                 vmlImg = document.createElement( 'v:image');\r
1273                                 vmlImg.src = url;\r
1274                                 loaded = true;\r
1275                                 resize( w, h);\r
1276                                 onLoadCallback && onLoadCallback( _url, _actualW, _actualH);\r
1277                                 onLoadCallback = null;\r
1278                         }\r
1279                         function onError( _url){\r
1280                                 if( elmWrap === null) return;\r
1281                                 elmWrap.className = CLASS_NAME_ERROR;\r
1282                                 retryTimer = setTimeout( function(){\r
1283                                         elmWrap.className = CLASS_NAME_LOADING;\r
1284                                         h2c.util.loadImage( url, onLoad, onError, 100, 10000);\r
1285                                 }, RETRY_DELAY);\r
1286                         }\r
1287                         function resize( _w, _h){\r
1288                                 w = _w !== undefined ? _w : w;\r
1289                                 h = _h !== undefined ? _h : h;\r
1290                                 if( loaded !== true) return;\r
1291                                 vmlImg.style.width = w < 0 ? -w : w +'px';\r
1292                                 vmlImg.style.height = h < 0 ? -h : h +'px';\r
1293                                 //if( flipH !== _flipH || flipV !== _flipV){\r
1294                                         vmlImg.parentNode === elmWrap && elmWrap.removeChild( vmlImg);\r
1295                                 //}\r
1296                                         vmlImg.className = w < 0 || h < 0 ? ( 'img-flip-' + ( w < 0 && h < 0 ? 'vh' : ( w < 0 ? 'v' : 'h'))) : '';\r
1297                                         elmWrap.appendChild( vmlImg);\r
1298                         }\r
1299                         return {\r
1300                                 elm : elmWrap,\r
1301                                 resize: resize,\r
1302                                 destroy: function(){\r
1303                                         loaded === true && elmWrap.removeChild( vmlImg);\r
1304                                         retryTimer !== null && clearTimeout( retryTimer);\r
1305                                         elmWrap = vmlImg = onLoadCallback = retryTimer = null;\r
1306                                         delete this.destroy;\r
1307                                 }\r
1308                         }\r
1309                 }\r
1310                 var serverImage = function( url, w, h, onLoadCallback){\r
1311                         \r
1312                 }\r
1313                 \r
1314                 return function( url, w, h, onLoadCallback){\r
1315                                 var flipH = w < 0,\r
1316                                         flipV = h < 0,\r
1317                                         onLoadCallbackAsync = onLoadCallback,// ? function(){ setTimeout( onLoadCallback, 0);} : undefined,// 一度読み込んだ画像は即座にonLoadになるため遅延\r
1318                                         xBackendImage = ( function( urlIsXDomain){\r
1319                                                 if( BACKEND === IS_CSS3) return css3Image.apply( {}, [ url, w, h, onLoadCallbackAsync]);\r
1320                                                 if( BACKEND === IS_VML) return vmlImage.apply( {}, [ url, w, h, onLoadCallbackAsync]);\r
1321                                                 if( BACKEND === IS_ACTIVEX) return activexImage.apply( {}, [ url, w, h, onLoadCallbackAsync]);\r
1322                                                 return serverImage.apply( {}, [ url, w, h, onLoadCallbackAsync]);\r
1323                                         })();\r
1324                                 return {\r
1325                                         elm: xBackendImage.elm,\r
1326                                         w: function( _w){\r
1327                                                 _w !== undefined && xBackendImage.resize( _w, h);\r
1328                                                 return w;\r
1329                                         },\r
1330                                         h: function( _h){\r
1331                                                 _h !== undefined && xBackendImage.resize( w, _h);\r
1332                                                 return h;\r
1333                                         },\r
1334                                         resize: xBackendImage.resize,\r
1335                                         destroy: function(){\r
1336                                                 xBackendImage.destroy && xBackendImage.destroy();\r
1337                                                 xBackendImage = onLoadCallback = onLoadCallbackAsync = null;\r
1338                                                 delete this.destroy;\r
1339                                         }\r
1340                                 }\r
1341                         }\r
1342         })();\r
1343         return {\r
1344                 init: function(){\r
1345                         \r
1346                 },\r
1347                 createReversibleImage: function( url, w, h, onLoadCallback){\r
1348                         return XBackendReversibleImageClass.apply( {}, [ url, w, h, onLoadCallback]);\r
1349                 }\r
1350         }\r
1351 })();\r
1352 \r
1353 /* ----------------------------------------\r
1354  *   h2c.editor\r
1355  *    - HISTORY\r
1356  *    - WINDOW_CONTROL\r
1357  *       - WINDOW_CLASS\r
1358  *    - INFOMATION_WINDOW\r
1359  *    - TOOL_BOX_WINDOW\r
1360  *    - CANVAS_CONTROL\r
1361  *       - GRID_CONTROL\r
1362  *       - WHITE_GLASS_CONTROL\r
1363  *       - PANEL_BORDER_CONTROL\r
1364  *       - COMIC_ELEMENT_CONTROL\r
1365  *          - PanelResizerClass\r
1366  *          - COMIC_ELEMENT_OPERATOR\r
1367  *             - TAIL_CONTROLER\r
1368  *          - ImageElementClass\r
1369  *          - TextElementClass\r
1370  * \r
1371  */\r
1372 h2c.editor = ( function(){\r
1373         var COMIC_ELEMENT_TYPE_IMAGE = 0,\r
1374                 COMIC_ELEMENT_TYPE_TEXT = 1,\r
1375                 MOUSE_LISTENER_ARRAY = [],\r
1376                 currentListener = null,\r
1377                 ELM_MOUSE_EVENT_CHATCHER = document.getElementById( 'mouse-operation-catcher'),\r
1378                 jqMouseEventChacher,\r
1379                 jqEditor,\r
1380                 windowW, windowH,\r
1381                 currentCursor = '';\r
1382 \r
1383 /* ----------------------------------------\r
1384  * MENU BAR\r
1385  * div\r
1386  *   div.title\r
1387  *   ul\r
1388  *     li\r
1389  *        a\r
1390  *          span\r
1391  *          kbd shortcut\r
1392  */\r
1393         var MENU_BAR_CONTROL = ( function(){\r
1394                 var BAR_ID = 'menu-bar',\r
1395                         ELM_BAR = document.getElementById( BAR_ID),\r
1396                         ELM_ITEM_CLASSNAME = 'menu-bar-item',\r
1397                         ELM_ITEM_ORIGN = ( function(){\r
1398                                 var ret = document.createElement( 'DIV'),\r
1399                                         div = document.createElement( 'DIV'),\r
1400                                         ul = document.createElement( 'UL');\r
1401                                 ret.className = ELM_ITEM_CLASSNAME;\r
1402                                 ret.appendChild( div);\r
1403                                 ret.appendChild( ul);\r
1404                                 return ret;\r
1405                         })(),\r
1406                         ELM_SELECTION_ORIGN = ( function(){\r
1407                                 var ret = document.createElement( 'LI'),\r
1408                                         a = document.createElement( 'A'),\r
1409                                         span = document.createElement( 'SPAN'),\r
1410                                         key = document.createElement( 'KBD');\r
1411                                 a.href = '#';\r
1412                                 a.appendChild( span);\r
1413                                 a.appendChild( key);\r
1414                                 ret.appendChild( a);\r
1415                                 return ret;\r
1416                         })(),\r
1417                         EMPTY_FUNCTION = new Function,\r
1418                         ITEM_ARRAY = [],\r
1419                         barH = h2c.util.getElementSize( ELM_BAR).height,\r
1420                         itemW = h2c.util.getElementSize( ELM_ITEM_ORIGN).width,\r
1421                         selectionW = h2c.util.getElementSize( ELM_ITEM_ORIGN.getElementsByTagName( 'UL')[ 0]).width,\r
1422                         jqStage, jqBar;\r
1423                 ELM_BAR.style.top = ( -barH) +'px';\r
1424 \r
1425                 var MenubarSelectionClass = function( container, title, shortcut, visible, separateAfter){\r
1426                         var ELM_WRAPPER = ELM_SELECTION_ORIGN.cloneNode( true),\r
1427                                 ELM_TITLE = ELM_WRAPPER.getElementsByTagName( 'SPAN')[ 0];\r
1428                         updateTitle( title);\r
1429                         updateVisible( visible);\r
1430                         \r
1431                         ( function(){\r
1432                                 var ELM_SHORTCUT = ELM_WRAPPER.getElementsByTagName( 'KBD')[ 0];\r
1433                                 if( shortcut){\r
1434                                         ELM_SHORTCUT.innerHTML = shortcut;\r
1435                                 } else {\r
1436                                         ELM_SHORTCUT.parentNode.removeChild( ELM_SHORTCUT);\r
1437                                 }                               \r
1438                         })();\r
1439 \r
1440                         container.appendChild( ELM_WRAPPER);\r
1441                         \r
1442                         function updateTitle( _title){\r
1443                                 ELM_TITLE.innerHTML = title = _title;\r
1444                         }\r
1445                         function updateVisible( _visible){\r
1446                                 _visible !== undefined && ( function(){\r
1447                                         visible = !!_visible;\r
1448                                         ELM_WRAPPER.className = visible === true ? '' : 'disabled';\r
1449                                 })();\r
1450                         }\r
1451                         return {\r
1452                                 elm: ELM_WRAPPER,\r
1453                                 title: function( _title){\r
1454                                         _title !== undefined && updateTitle( _title);\r
1455                                         return title;\r
1456                                 },\r
1457                                 visible: function( _visible){\r
1458                                         visible !== !!_visible && updateVisible( _visible);\r
1459                                         return visible;\r
1460                                 },\r
1461                                 separateAfter: separateAfter\r
1462                         }\r
1463                 }\r
1464 \r
1465                 var MenuBarItemClass = function( title, opt_callbackArray){\r
1466                         var ELM_WRAPPER = ELM_ITEM_ORIGN.cloneNode( true),\r
1467                                 ELM_TITLE = ELM_WRAPPER.getElementsByTagName( 'DIV')[ 0],\r
1468                                 ELM_SELECTION = ELM_WRAPPER.getElementsByTagName( 'UL')[ 0],\r
1469                                 INDEX = ITEM_ARRAY.length,\r
1470                                 SELECTION_CALLBACK_ARRAY = opt_callbackArray || [],\r
1471                                 numSelection = 0,\r
1472                                 visible = false;\r
1473                         ELM_TITLE.innerHTML = title;\r
1474                         \r
1475                         ELM_WRAPPER.style.left = ( itemW * INDEX) +'px';\r
1476                         ELM_BAR.appendChild( ELM_WRAPPER);\r
1477                         \r
1478                         function onClick( e){\r
1479                                 var that = this,\r
1480                                         i = ( function(){\r
1481                                                 var parent = that.parentNode,\r
1482                                                         children = parent.getElementsByTagName( 'LI'),\r
1483                                                         l = children.length;\r
1484                                                 for(var i=0; i<l; ++i){\r
1485                                                         if( children[ i] === that) return i;\r
1486                                                 }\r
1487                                                 return -1;\r
1488                                         })();\r
1489                                 i !== -1 && this.className !== 'disabled' && SELECTION_CALLBACK_ARRAY[ i]();\r
1490                                 e.stopPropagation();\r
1491                                 return false;                           \r
1492                         }\r
1493                         return {\r
1494                                 elm: ELM_WRAPPER,\r
1495                                 onClick: onClick,\r
1496                                 init: function(){\r
1497                                         $( ELM_SELECTION).children( 'li').click( onClick);\r
1498                                         delete this.init;\r
1499                                 },\r
1500                                 show: function(){\r
1501                                         if( visible === true) return;\r
1502                                         jqStage.append( ELM_WRAPPER);\r
1503                                         ELM_WRAPPER.className = ELM_ITEM_CLASSNAME +'-focus';\r
1504                                         this.onShow && setTimeout( this.onShow, 0);\r
1505                                         visible = true;\r
1506                                 },\r
1507                                 hide: function(){\r
1508                                         if( visible === false) return;\r
1509                                         ELM_BAR.appendChild( ELM_WRAPPER);\r
1510                                         ELM_WRAPPER.className = ELM_ITEM_CLASSNAME;\r
1511                                         this.onHide && setTimeout( this.onHide, 0);\r
1512                                         visible = false;\r
1513                                 },\r
1514                                 createSelection: function( title, shortcut, callback, visible, separateBefore, separateAfter){\r
1515                                         var ret = MenubarSelectionClass.apply( {}, [ ELM_SELECTION, title, shortcut, visible, separateAfter]),\r
1516                                                 before = SELECTION_CALLBACK_ARRAY.length > 0 ? SELECTION_CALLBACK_ARRAY[ SELECTION_CALLBACK_ARRAY.length -1] : null;\r
1517                                         SELECTION_CALLBACK_ARRAY.push( callback);\r
1518                                         if( ( separateBefore === true && before) || ( before && before.separateAfter === true)){\r
1519                                                 ret.elm.style.borderTop = '1px solid #ccc';\r
1520                                         }\r
1521                                         return ret;\r
1522                                 }\r
1523                         }\r
1524                 }\r
1525 \r
1526                 \r
1527                 function createMenubarItem( title){\r
1528                         var _item = MenuBarItemClass.apply( {}, [ title]);\r
1529                         ITEM_ARRAY.push( _item);\r
1530                         return _item;\r
1531                 }\r
1532                 return {\r
1533                         init: function(){\r
1534                                 jqStage = jqEditor;\r
1535                                 jqBar = $( '#' +BAR_ID).animate( { top: 0});\r
1536 \r
1537                                 var l = ITEM_ARRAY.length;\r
1538                                 for( var i=0; i<l; ++i){\r
1539                                         ITEM_ARRAY[ i].init();\r
1540                                 }\r
1541 \r
1542                                 delete MENU_BAR_CONTROL.init;\r
1543                         },\r
1544                         h: barH,\r
1545                         onMouseMove: function( _mouseX, _mouseY){\r
1546                                 if( barH >= _mouseY){\r
1547                                         return true;\r
1548                                 }\r
1549                                 var l = ITEM_ARRAY.length;\r
1550                                 for( var i=0; i<l; ++i){\r
1551                                         ITEM_ARRAY[ i].hide();\r
1552                                 }\r
1553                                 return false;\r
1554                         },\r
1555                         onMouseUp: function( _mouseX, _mouseY){\r
1556                                 return false;\r
1557                         },\r
1558                         onMouseDown: function( _mouseX, _mouseY){\r
1559                                 var l = ITEM_ARRAY.length;\r
1560                                 if( barH < _mouseY || itemW * l < _mouseX) return false;\r
1561                                 for( var i=0; i<l; ++i){\r
1562                                         if( i * itemW <= _mouseX && _mouseX < ( i +1) * itemW){\r
1563                                                 ITEM_ARRAY[ i].show();\r
1564                                         } else {\r
1565                                                 ITEM_ARRAY[ i].hide();\r
1566                                         }\r
1567                                 }\r
1568                                 return true;\r
1569                         },\r
1570                         busy: function( _busy){\r
1571                                 return false;\r
1572                         },\r
1573                         onWindowResize: function( _windowW, _windowH){\r
1574                                 \r
1575                         },\r
1576                         QUIT: createMenubarItem( 'Quit'),\r
1577                         EDIT: createMenubarItem( 'Edit'),\r
1578                         WINDOW: createMenubarItem( 'Window'),\r
1579                         HELP: h2c.util.extend( createMenubarItem( 'Help'), {\r
1580                                         createAjaxSelection: function( callback){\r
1581                                                 var elmLoading = document.createElement( 'li'),\r
1582                                                         that = this,\r
1583                                                         elmSelection = this.elm.getElementsByTagName( 'UL')[ 0];\r
1584                                                 elmSelection.appendChild( elmLoading);\r
1585                                                 elmLoading.className = 'loading';\r
1586                                                 elmLoading.style.height = '90px';                                                       \r
1587 \r
1588                                                 this.onShow = callback;\r
1589                                                 callback = null;\r
1590                                                 \r
1591                                                 delete this.createAjaxSelection;\r
1592                                                 return function(){\r
1593                                                         elmSelection.removeChild( elmLoading);\r
1594                                                         $( elmSelection).children( 'li').click( that.onClick);\r
1595                                                         elmLoading = elmSelection = null;\r
1596                                                         delete that.onShow;\r
1597                                                         that = null;\r
1598                                                 }\r
1599                                         }\r
1600                                 })\r
1601                 }\r
1602         })();\r
1603 \r
1604 \r
1605 /* ----------------------------------------\r
1606  * HISTORY\r
1607  */\r
1608         var HISTORY = ( function() {\r
1609                 var     STACK_BACK = [],\r
1610                         STACK_FORWARD = [],\r
1611                         MENUBAR_BACK = MENU_BAR_CONTROL.EDIT.createSelection( 'back', 'ctrl + z', back, false),\r
1612                         MENUBAR_FORWARD = MENU_BAR_CONTROL.EDIT.createSelection( 'forward', 'ctrl + y', forward, false, false, true),\r
1613                         log;\r
1614                         \r
1615                 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 90, false, true, back);       // ctrl + Z\r
1616                 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 90, true, true, forward);     // ctrl + shift + Z\r
1617                 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 89, false, true, forward); // ctrl + Y\r
1618 \r
1619                 function back(){\r
1620                         /*\r
1621                          * currentを控えてSTACK_FORWARD.push(current)\r
1622                          * STACK_BACK.pop()を実行してcurrentに\r
1623                          */\r
1624                         if( STACK_BACK.length === 0) return;\r
1625 \r
1626                         var state = STACK_BACK.pop();\r
1627                         state && state.fn( state.argBack);\r
1628                         MENUBAR_BACK.visible( STACK_BACK.length !== 0);\r
1629                         SAVE_CONTROL.panelUpdated( STACK_BACK.length !== 0);\r
1630                         \r
1631                         STACK_FORWARD.push( state);\r
1632                         MENUBAR_FORWARD.visible( true);\r
1633                 }\r
1634                 function forward(){\r
1635                         if( STACK_FORWARD.length === 0) return;\r
1636                         \r
1637                         var state = STACK_FORWARD.pop();\r
1638                         state.fn( state.argForword);\r
1639                         MENUBAR_FORWARD.visible( STACK_FORWARD.length !== 0);\r
1640                         \r
1641                         STACK_BACK.push( state);\r
1642                         MENUBAR_BACK.visible( true);\r
1643                         SAVE_CONTROL.panelUpdated( true);\r
1644                 }\r
1645                 return {\r
1646                         init: function(){\r
1647                                 log = $( '#history-log');\r
1648                                 delete HISTORY.init;\r
1649                         },\r
1650                     saveState: function( _function, _argBack, _argForword, _destory) {\r
1651                         STACK_BACK.push( {\r
1652                                 fn:                     _function,\r
1653                                 argBack:        _argBack,\r
1654                                         argForword:     _argForword,\r
1655                                         destroy:        _destroy\r
1656                         });\r
1657                         MENUBAR_BACK.visible( true);\r
1658                                 SAVE_CONTROL.panelUpdated( true);\r
1659 \r
1660                         while( STACK_FORWARD.length > 0){\r
1661                                         _argBack = _stack.argBack;\r
1662                                         _argForword = _stack.argForword;                                        \r
1663                                         var _stack = STACK_FORWARD.shift(),\r
1664                                                 _destroy = _stack.destroy,\r
1665                                                 _value;\r
1666                                         _stack.fn = null;\r
1667                                         if( typeof _argBack === 'array'){\r
1668                                                 while( _argBack.length > 0){\r
1669                                                         _value = _argBack.shift();\r
1670                                                         _destroy === true && _value.destroy && _value.destroy();\r
1671                                                 }\r
1672                                         }\r
1673                                         if( typeof _argForword === 'array'){\r
1674                                                 while( _argForword.length > 0){\r
1675                                                         _value = _argForword.shift();\r
1676                                                         _destroy === true && _value.destroy && _value.destroy();\r
1677                                                 }                                               \r
1678                                         }\r
1679                                 }\r
1680                                 MENUBAR_FORWARD.visible( false);\r
1681                     }           \r
1682                 }\r
1683         })();\r
1684 \r
1685 \r
1686 /* ----------------------------------------\r
1687  *     Save Control\r
1688  */\r
1689 \r
1690         var SAVE_CONTROL = ( function(){\r
1691                 var SAVE = MENU_BAR_CONTROL.QUIT.createSelection( 'save', 'ctrl + S', quit, false),\r
1692                         SAVE_AND_QUIT = MENU_BAR_CONTROL.QUIT.createSelection( 'save & quit', null, quit, false, false, true),\r
1693                         SAVE_AS_HTML = MENU_BAR_CONTROL.QUIT.createSelection( 'get as html', null, outputAsHtml, true, false, true),\r
1694                         SAVE_AS_JSON_STRING = MENU_BAR_CONTROL.QUIT.createSelection( 'get JsonStr', null, outputAsJsonString, true, false, true),\r
1695                         QUIT = MENU_BAR_CONTROL.QUIT.createSelection( 'quit', null, quit, true, true),\r
1696                         updated = false;\r
1697                 \r
1698                 function quit(){\r
1699                 }\r
1700                 \r
1701                 function outputAsHtml(){\r
1702                         alert( CANVAS_CONTROL.getAsHTML( true, false));\r
1703                 }\r
1704                 function outputAsJsonString(){\r
1705                         alert( CANVAS_CONTROL.getAsJsonString());\r
1706                 }\r
1707                 return {\r
1708                         quit: quit,\r
1709                         panelUpdated: function( _updated){\r
1710                                 if( _updated !== undefined && updated !== _updated){\r
1711                                         SAVE.visible( !!_updated);\r
1712                                         SAVE_AND_QUIT.visible( !!_updated);\r
1713                                         updated = !!_updated;\r
1714                                 }\r
1715                                 return updated;\r
1716                         },\r
1717                         save: function(){\r
1718                                 \r
1719                         }\r
1720                 }\r
1721         })();\r
1722 \r
1723 /* ----------------------------------------\r
1724  *     Text Editor (Overlay)\r
1725  */\r
1726         \r
1727         var TEXT_EDITOR_CONTROL = ( function(){\r
1728                 var jqWrap, jqTextarea, jqButton,\r
1729                         textElement, onUpdateFunction;\r
1730                 \r
1731                 h2c.key.addKeyDownEvent( this.ID, 69, false, false, clickOK);\r
1732                 \r
1733                 function close(){\r
1734                         jqWrap.hide();\r
1735                         textElement = onUpdateFunction = null;          \r
1736                 }\r
1737                 function clickOK(){\r
1738                         h2c.overlay.hide();\r
1739                         textElement && textElement.text( jqTextarea.val());\r
1740                         onUpdateFunction && onUpdateFunction( textElement);\r
1741                         close();                        \r
1742                 }\r
1743                 return {\r
1744                         init: function(){\r
1745                                 this.jqWrap = jqWrap = $( '#speach-editor-wrapper').hide();\r
1746                                 jqTextarea = $( '#speach-editor').keydown( function( e){\r
1747                                         if( e.keyCode === 69 && e.shiftKey === false && e.ctrlKey === true){\r
1748                                                 clickOK();\r
1749                                                 e.preventDefault();\r
1750                                         e.keyCode = 0;\r
1751                                         e.cancelBubble = true;\r
1752                                         e.returnValue = false;\r
1753                                                 return false;\r
1754                                         }\r
1755                                 });\r
1756                                 jqButton = $( '#speach-edit-complete-button').click( clickOK);\r
1757                                 delete TEXT_EDITOR_CONTROL.init;\r
1758                         },\r
1759                         jqWrap: null,\r
1760                         show: function( _textElement, _onUpdateFunction){\r
1761                                 textElement = _textElement;\r
1762                                 onUpdateFunction = _onUpdateFunction || null;\r
1763                                 h2c.overlay.show( this);\r
1764                                 var h = _textElement.h;\r
1765                                 jqWrap.show().css( {\r
1766                                         left:                   _textElement.x +CANVAS_CONTROL.x(),\r
1767                                         top:                    _textElement.y +CANVAS_CONTROL.y(),\r
1768                                         width:                  _textElement.w,\r
1769                                         height:                 h\r
1770                                 });\r
1771                                 jqTextarea.val( _textElement.text()).focus();\r
1772                                 \r
1773                                 /*\r
1774                                  * ie6,7は、textarea { width:100%}でも高さが変わらない。rowsを設定。\r
1775                                  */\r
1776                                 h2c.isIE === true && h2c.ieVersion <= 7 && setTimeout( function(){\r
1777                                         var rows = 0;\r
1778                                         while( jqTextarea.height() < h){\r
1779                                                 rows++;\r
1780                                                 jqTextarea.attr( 'rows', rows);\r
1781                                         }\r
1782                                         rows > 1 && jqTextarea.attr( 'rows', rows -1);\r
1783                                 }, 0);\r
1784                         },\r
1785                         onWindowResize: function(){\r
1786                                 textElement && this.show( textElement);\r
1787                         },\r
1788                         onClose: close,\r
1789                         ID: 'textEditor'\r
1790                 }\r
1791         })();\r
1792 \r
1793 /* ----------------------------------------\r
1794  *     Image Group Exproler (Overlay)\r
1795  */\r
1796         var IMAGE_GROUP_EXPROLER = ( function(){\r
1797                 var ICON_ARRAY = [],\r
1798                         WHEEL_DELTA = 64,\r
1799                         containerW, containerH, wrapX,\r
1800                         jqWrap, jqContainer, jqItemOrigin,\r
1801                         itemW, itemH,\r
1802                         jqName, jqButton, buttonW,\r
1803                         onUpdateFunction,\r
1804                         winW,\r
1805                         onEnterInterval = null;\r
1806                 \r
1807                 var BASE_PATH = h2c.LOCAL === false ? 'http://pettan.heroku.com/images/' : 'images/',\r
1808                         THUMB_PATH = BASE_PATH, // + 'thumbnail/',\r
1809                         LIMIT_FILESIZE = 1024 * 10; // 10KB\r
1810                 var IMAGE_DATA = {\r
1811                                 pen001: [\r
1812                                     {\r
1813                                         "created_at": "2011-11-13T08:57:39Z", \r
1814                                         "ext": "png", \r
1815                                         "filesize": 9969, \r
1816                                         "height": 463, \r
1817                                         "id": 1, \r
1818                                         "updated_at": "2011-11-13T08:57:39Z", \r
1819                                         "width": 441\r
1820                                     }, \r
1821                                     {\r
1822                                         "created_at": "2011-11-13T08:57:54Z", \r
1823                                         "ext": "gif", \r
1824                                         "filesize": 5418, \r
1825                                         "height": 500, \r
1826                                         "id": 2, \r
1827                                         "updated_at": "2011-11-13T08:57:54Z", \r
1828                                         "width": 500\r
1829                                     }, \r
1830                                     {\r
1831                                         "created_at": "2011-11-13T08:58:06Z", \r
1832                                         "ext": "gif", \r
1833                                         "filesize": 8758, \r
1834                                         "height": 464, \r
1835                                         "id": 3, \r
1836                                         "updated_at": "2011-11-13T08:58:06Z", \r
1837                                         "width": 366\r
1838                                     }, \r
1839                                     {\r
1840                                         "created_at": "2011-11-13T08:58:23Z", \r
1841                                         "ext": "gif", \r
1842                                         "filesize": 9383, \r
1843                                         "height": 480, \r
1844                                         "id": 4, \r
1845                                         "updated_at": "2011-11-13T08:58:23Z", \r
1846                                         "width": 392\r
1847                                     }, \r
1848                                     {\r
1849                                         "created_at": "2011-11-13T08:58:33Z", \r
1850                                         "ext": "gif", \r
1851                                         "filesize": 11061, \r
1852                                         "height": 500, \r
1853                                         "id": 5, \r
1854                                         "updated_at": "2011-11-13T08:58:33Z", \r
1855                                         "width": 500\r
1856                                     }, \r
1857                                     {\r
1858                                         "created_at": "2011-11-20T09:50:43Z", \r
1859                                         "ext": "gif", \r
1860                                         "filesize": 1131, \r
1861                                         "height": 126, \r
1862                                         "id": 6, \r
1863                                         "updated_at": "2011-11-20T09:50:43Z", \r
1864                                         "width": 259\r
1865                                     }, \r
1866                                     {\r
1867                                         "created_at": "2011-11-20T09:50:55Z", \r
1868                                         "ext": "gif", \r
1869                                         "filesize": 1125, \r
1870                                         "height": 126, \r
1871                                         "id": 7, \r
1872                                         "updated_at": "2011-11-20T09:50:55Z", \r
1873                                         "width": 259\r
1874                                     }, \r
1875                                     {\r
1876                                         "created_at": "2011-11-20T11:33:12Z", \r
1877                                         "ext": "gif", \r
1878                                         "filesize": 17919, \r
1879                                         "height": 600, \r
1880                                         "id": 8, \r
1881                                         "updated_at": "2011-11-20T11:33:12Z", \r
1882                                         "width": 800\r
1883                                     },\r
1884                                     {\r
1885                                         "created_at": "2011-11-20T11:33:12Z", \r
1886                                         "ext": "gif", \r
1887                                         "filesize": 17919, \r
1888                                         "height": 600, \r
1889                                         "id": 9, \r
1890                                         "updated_at": "2011-11-20T11:33:12Z", \r
1891                                         "width": 800\r
1892                                     },\r
1893                                     {\r
1894                                         "created_at": "2011-11-20T11:33:12Z", \r
1895                                         "ext": "gif", \r
1896                                         "filesize": 17919, \r
1897                                         "height": 600, \r
1898                                         "id": 10, \r
1899                                         "updated_at": "2011-11-20T11:33:12Z", \r
1900                                         "width": 800\r
1901                                     },\r
1902                                     {\r
1903                                         "created_at": "2011-11-20T11:33:12Z", \r
1904                                         "ext": "gif", \r
1905                                         "filesize": 17919, \r
1906                                         "height": 600, \r
1907                                         "id": 11, \r
1908                                         "updated_at": "2011-11-20T11:33:12Z", \r
1909                                         "width": 800\r
1910                                     },\r
1911                                     {\r
1912                                         "created_at": "2011-11-22T09:17:20Z", \r
1913                                         "ext": "gif", \r
1914                                         "filesize": 9055, \r
1915                                         "height": 473, \r
1916                                         "id": 12, \r
1917                                         "updated_at": "2011-11-22T09:17:20Z", \r
1918                                         "width": 405\r
1919                                     }, \r
1920                                     {\r
1921                                         "created_at": "2011-11-22T10:11:07Z", \r
1922                                         "ext": "gif", \r
1923                                         "filesize": 8758, \r
1924                                         "height": 464, \r
1925                                         "id": 13, \r
1926                                         "updated_at": "2011-11-22T10:11:07Z", \r
1927                                         "width": 366\r
1928                                     }, \r
1929                                     {\r
1930                                         "created_at": "2011-11-24T09:05:12Z", \r
1931                                         "ext": "gif", \r
1932                                         "filesize": 6431, \r
1933                                         "height": 386, \r
1934                                         "id": 16, \r
1935                                         "updated_at": "2011-11-24T09:05:12Z", \r
1936                                         "width": 453\r
1937                                     }, \r
1938                                     {\r
1939                                         "created_at": "2011-11-26T04:52:12Z",\r
1940                                         "ext": "gif", \r
1941                                         "filesize": 6421, \r
1942                                         "height": 426, \r
1943                                         "id": 17, \r
1944                                         "updated_at": "2011-11-26T04:52:12Z", \r
1945                                         "width": 306\r
1946                                     }, \r
1947                                     {\r
1948                                         "created_at": "2011-11-26T04:52:12Z",\r
1949                                         "ext": "gif", \r
1950                                         "filesize": 6421, \r
1951                                         "height": 426, \r
1952                                         "id": 18, \r
1953                                         "updated_at": "2011-11-26T04:52:12Z", \r
1954                                         "width": 306\r
1955                                     }, \r
1956                                     {\r
1957                                         "created_at": "2011-11-26T04:52:12Z",\r
1958                                         "ext": "gif", \r
1959                                         "filesize": 6421, \r
1960                                         "height": 426, \r
1961                                         "id": 19, \r
1962                                         "updated_at": "2011-11-26T04:52:12Z", \r
1963                                         "width": 306\r
1964                                     }, \r
1965                                     {\r
1966                                         "created_at": "2011-11-26T04:52:12Z",\r
1967                                         "ext": "gif", \r
1968                                         "filesize": 6421, \r
1969                                         "height": 426, \r
1970                                         "id": 20, \r
1971                                         "updated_at": "2011-11-26T04:52:12Z", \r
1972                                         "width": 306\r
1973                                     }, \r
1974                                     {\r
1975                                         "created_at": "2011-11-26T04:52:12Z",\r
1976                                         "ext": "gif", \r
1977                                         "filesize": 6421, \r
1978                                         "height": 426, \r
1979                                         "id": 21, \r
1980                                         "updated_at": "2011-11-26T04:52:12Z",\r
1981                                         "width": 306\r
1982                                     }\r
1983                                 ]\r
1984                         }\r
1985                 \r
1986                 var ImageGroupIconClass = function( INDEX, data){\r
1987                         var JQ_ICON_WRAP = jqItemOrigin.clone( true),\r
1988                                 SRC = [ BASE_PATH, data.id, '.', data.ext].join( ''),\r
1989                                 LOW_SRC = data.filesize && data.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext].join( '') : null,\r
1990                                 reversibleImage = null,\r
1991                                 onEnterFlag = false;\r
1992                         JQ_ICON_WRAP.children( 'div').eq( 0).html( data.filesize + 'bytes');\r
1993                         jqContainer.append( JQ_ICON_WRAP.css( { left: INDEX * itemW}));\r
1994                         \r
1995                         return {\r
1996                                 onEnter: function(){\r
1997                                         if( onEnterFlag === true) return;\r
1998                                         reversibleImage = h2c.image.createReversibleImage( LOW_SRC || SRC, itemW, itemH, function( url, imgW, imgH){\r
1999                                                 if( reversibleImage === null) {\r
2000                                                         alert( url);\r
2001                                                         return;\r
2002                                                 }\r
2003                                                 /*\r
2004                                                  * ieでサイズが取れない、、、\r
2005                                                  */\r
2006                                                 imgW = imgW || data.width || 64;\r
2007                                                 imgH = imgH || data.height || 64;\r
2008                                                 JQ_ICON_WRAP.children( 'div').eq( 1).html( imgW +'x' +imgH);\r
2009                                                 var zoom = 128 /( imgW > imgH ? imgW : imgH),\r
2010                                                         h = Math.floor( imgH *zoom),\r
2011                                                         w = Math.floor( imgW *zoom);\r
2012                                                 reversibleImage.elm.style.width = w +'px';\r
2013                                                 reversibleImage.elm.style.height = h +'px';\r
2014                                                 reversibleImage.elm.style.margin = Math.floor( itemH /2 -h /2)+'px 0 0';\r
2015                                                 reversibleImage.resize( w, h);\r
2016                                                 JQ_ICON_WRAP.click( function( e){\r
2017                                                         h2c.overlay.hide();\r
2018                                                         if (onUpdateFunction) {\r
2019                                                                 if( LOW_SRC === null){\r
2020                                                                         onUpdateFunction( SRC, imgW, imgH);\r
2021                                                                 } else {\r
2022                                                                         ( function( onUpdate){\r
2023                                                                                 h2c.util.loadImage( SRC,\r
2024                                                                                         function( _abspath, imgW, imgH){\r
2025                                                                                                 onUpdate( SRC, imgW, imgH);\r
2026                                                                                                 onUpdate = null;\r
2027                                                                                         },\r
2028                                                                                         function( _abspath){\r
2029                                                                                                 onUpdate( SRC, data.width || 64, data.height || 64);\r
2030                                                                                                 onUpdate = null;\r
2031                                                                                         }\r
2032                                                                                 );                                                                              \r
2033                                                                         })( onUpdateFunction); // close()で値が消えるので、クロージャに保持\r
2034                                                                 }\r
2035                                                         }\r
2036                                                         close();\r
2037                                                 });\r
2038                                         });\r
2039                                         JQ_ICON_WRAP.children( 'img').replaceWith( reversibleImage.elm);\r
2040                                         onEnterFlag = true;                             \r
2041                                 },\r
2042                                 destroy: function(){\r
2043                                         reversibleImage && reversibleImage.destroy();\r
2044                                         JQ_ICON_WRAP.remove();\r
2045                                         reversibleImage = JQ_ICON_WRAP = null;\r
2046                                         delete this.destroy;\r
2047                                 }\r
2048                         }\r
2049                 }\r
2050                 \r
2051                 function close(){\r
2052                         jqContainer.stop().animate( {\r
2053                                         height: 0,\r
2054                                         top:    Math.floor( windowH /2)\r
2055                                 }, function(){\r
2056                                         jqWrap.hide()\r
2057                                 });\r
2058                         while( ICON_ARRAY.length > 0){\r
2059                                 ICON_ARRAY.shift().destroy();\r
2060                         }\r
2061                         onEnterInterval !== null && window.clearTimeout( onEnterInterval);\r
2062                         onUpdateFunction = onEnterInterval = null;\r
2063                 }\r
2064                 function onEnterShowImage(){\r
2065                         var l = ICON_ARRAY.length,\r
2066                                 _start = -wrapX /itemW -1,\r
2067                                 _end = _start + winW /itemW +1;\r
2068                         for( var i=0; i<l; ++i){\r
2069                                 _start < i && i < _end && ICON_ARRAY[ i].onEnter();\r
2070                         }\r
2071                         onEnterInterval !== null && window.clearTimeout( onEnterInterval);\r
2072                         onEnterInterval = null;\r
2073                 }\r
2074                 function clickOK(){\r
2075                         h2c.overlay.hide();\r
2076                         // onUpdateFunction && onUpdateFunction( textElement);\r
2077                         close();\r
2078                 }\r
2079                 return {\r
2080                         init: function(){\r
2081                                 this.jqWrap = jqWrap = $( '#image-gruop-wrapper').hide();\r
2082                                 jqContainer = $( '#image-icon-container').mousewheel(\r
2083                                         function( e, delta){\r
2084                                                 if( winW < containerW){\r
2085                                                         wrapX += delta *WHEEL_DELTA;\r
2086                                                         wrapX = wrapX > 0 ? 0 : wrapX < winW -containerW ? winW -containerW : wrapX;\r
2087                                                         jqContainer.css( { left: wrapX});\r
2088                                                         \r
2089                                                         onEnterInterval !== null && window.clearTimeout( onEnterInterval);\r
2090                                                         onEnterInterval = window.setTimeout( onEnterShowImage, 500);\r
2091                                                 }\r
2092                                                 //e.stopPropagation();\r
2093                                                 return false;\r
2094                                         });\r
2095                                 containerH = h2c.util.getElementSize( jqContainer.get( 0)).height;\r
2096                                 jqItemOrigin = $( $( '#imageGruopItemTemplete').remove().html());\r
2097                                 var itemSize = h2c.util.getElementSize( jqItemOrigin.get( 0));\r
2098                                 itemW = itemSize.width;\r
2099                                 itemH = itemSize.height;\r
2100                                 jqName = $( '#gruop-name-display');\r
2101                                 jqButton = $( '#image-gruop-button').click( clickOK);\r
2102                                 buttonW = h2c.util.getElementSize( jqButton.get( 0)).width;\r
2103                                 \r
2104                                 delete IMAGE_GROUP_EXPROLER.init;\r
2105                         },\r
2106                         jqWrap: null,\r
2107                         show: function( _onUpdateFunction){\r
2108                                 onUpdateFunction = _onUpdateFunction;\r
2109                                 h2c.overlay.show( this);\r
2110                                 \r
2111                                 var CURRENT_GROUP_ARRAY = IMAGE_DATA[ 'pen001'] || [],\r
2112                                         l = CURRENT_GROUP_ARRAY.length;\r
2113                                 for( var i=0; i<l; ++i){\r
2114                                         ICON_ARRAY.push( ImageGroupIconClass.apply( {}, [ i, CURRENT_GROUP_ARRAY[ i]]));\r
2115                                 }\r
2116                                 wrapX = 0;\r
2117                                 containerW = l * itemW;\r
2118                                 \r
2119                                 winW = windowW;\r
2120                                 var w = winW > containerW ? winW : containerW,\r
2121                                         h = windowH > containerH ? containerH : windowH;\r
2122                                 \r
2123                                 jqWrap.show();\r
2124                                 jqContainer.css( {\r
2125                                         width:          w,\r
2126                                         height:         0,\r
2127                                         left:           0,\r
2128                                         top:            Math.floor( windowH /2)\r
2129                                 }).stop().animate( {\r
2130                                         height:         h,\r
2131                                         top:            Math.floor( windowH /2 -h /2)\r
2132                                 });\r
2133                                 \r
2134                                 jqButton.css( {\r
2135                                         left:           Math.floor( winW /2 -buttonW /2),\r
2136                                         top:            Math.floor( windowH /2 +containerH /2 +10)\r
2137                                 });\r
2138                                 \r
2139                                 onEnterShowImage();\r
2140                         },\r
2141                         onWindowResize: function( _windowW, _windowH){\r
2142                                 var w = _windowW > containerW ? _windowW : containerW,\r
2143                                         h = _windowH > containerH ? containerH : _windowH,\r
2144                                         offsetW = Math.floor( _windowW /2 -winW /2);\r
2145                                 winW = _windowW;\r
2146                                 if( offsetW <= 0){ // smaller\r
2147                                         jqContainer.css( {\r
2148                                                 left:                           offsetW,\r
2149                                                 width:                          w\r
2150                                         }).animate( {\r
2151                                                 left:                           0,\r
2152                                                 top:                            Math.floor( _windowH /2 -h /2)\r
2153                                         });                                     \r
2154                                 } else {\r
2155                                         jqContainer.css( { // bigger\r
2156                                                 left:                           0,\r
2157                                                 width:                          w,\r
2158                                                 borderLeftWidth:        offsetW\r
2159                                         }).animate( {\r
2160                                                 top:                            Math.floor( _windowH /2 -h /2),\r
2161                                                 borderLeftWidth:        0\r
2162                                         });\r
2163                                 }\r
2164                                 jqButton.css( {\r
2165                                         left:           Math.floor( _windowW /2 -buttonW /2),\r
2166                                         top:            Math.floor( _windowH /2 +containerH /2 +10)\r
2167                                 });\r
2168                                 onEnterShowImage();\r
2169                         },\r
2170                         onClose: close,\r
2171                         ID: 'imageGroupExproler'\r
2172                 }\r
2173         })();\r
2174 \r
2175 /* ----------------------------------------\r
2176  * WINDOWS_CONTROL\r
2177  */     \r
2178         var WINDOWS_CONTROL = ( function(){\r
2179                 /*\r
2180                  *  表示上手前にあるwindowは、WINDOW_ARRAYの先頭にあり、htmlでは後ろにある。\r
2181                  */\r
2182                 var DEFAULT_MIN_WINDOW_WIDTH = 200,\r
2183                         DEFAULT_MIN_WINDOW_HEIGHT = 200,\r
2184                         WINDOW_ARRAY = [],\r
2185                         jqContainer,\r
2186                         currentWindow,\r
2187                         currentWindowIndex = -1,\r
2188                         log;\r
2189 \r
2190                 var jqWindowOrigin,\r
2191                         closeButtonWidth;\r
2192                 var WindowClass = function( bodyTempleteID, title, x, y, w, h, visible, CLOSE_BUTTON_ENABLED, RESIZE_BUTTON_ENABLED, minWindowW, minWindowH){\r
2193                         var MOUSE_CURSOR = updateMouseCursor,\r
2194                                 MENUBAR_SELWCTION = MENU_BAR_CONTROL.WINDOW.createSelection( \r
2195                                         ( visible !== true ? 'show ' : 'hide ') +title,\r
2196                                         null,\r
2197                                         function(){\r
2198                                                 visible === true ? instance.close() : instance.open();\r
2199                                         }, true\r
2200                                 ),\r
2201                                 jqStage,\r
2202                                 jqWrapper, jqHeader, elmBody, elmBodyStyle,\r
2203                                 startX, startY, startW, startH,\r
2204                                 xOffset, yOffset,\r
2205                                 headerH, bodyH,\r
2206                                 isDragging = false,\r
2207                                 isResizing = false,\r
2208                                 bodyIsTachable = false,\r
2209                                 instance;\r
2210                         \r
2211                         function update( _x, _y, _w, _h){\r
2212                                 ( w !== _w || h !== _h) && instance.onResize && instance.onResize( _w, _h);\r
2213                                 x = _x !== undefined ? _x : x;\r
2214                                 y = _y !== undefined ? _y : y;\r
2215                                 w = _w !== undefined ? _w : w;\r
2216                                 h = _h !== undefined ? _h : h;\r
2217                                 y = y > MENU_BAR_CONTROL.h ? y : MENU_BAR_CONTROL.h;\r
2218                                 jqWrapper.css( {\r
2219                                         left:           x,\r
2220                                         top:            y,\r
2221                                         width:          w,\r
2222                                         height:         h\r
2223                                 });\r
2224                                 bodyH = h -headerH;\r
2225                                 elmBodyStyle.height = bodyH +'px';\r
2226                         }\r
2227                         function bodyBackOrForward( isBack){\r
2228                                 if( !instance) return;\r
2229                                 if( bodyIsTachable === !isBack) return;\r
2230                                 elmBodyStyle.position = isBack === true ? 'relative' : 'absolute';\r
2231                                 elmBodyStyle.left =             isBack === true ? 0  : x +'px';\r
2232                                 elmBodyStyle.top =              isBack === true ? 0  : y +headerH +'px';\r
2233                                 elmBodyStyle.width =    isBack === true ? '' : w +'px';\r
2234                                 bodyIsTachable === isBack && isBack === true ? jqWrapper.append( elmBody) : jqStage.append( elmBody);\r
2235                                 bodyIsTachable = !isBack;\r
2236                         }\r
2237                         function onWindowResize( e){\r
2238                                 bodyBackOrForward( true);\r
2239                                 isResizing = true;\r
2240                                 startX = x;\r
2241                                 startY = y;\r
2242                                 startW = w;\r
2243                                 startH = h;\r
2244                                 xOffset = e.pageX;\r
2245                                 yOffset = e.pageY;\r
2246                                 MOUSE_CURSOR( 'nw-resize');\r
2247                                 e.stopPropagation();\r
2248                                 return false;\r
2249                         }\r
2250                         return {\r
2251                                 init: function( jqContainer){\r
2252                                         /*\r
2253                                          * setTimeout で呼ばれるグローバルメソッドは、this でなく instance を使う.\r
2254                                          */\r
2255                                         instance = this;\r
2256                                         \r
2257                                         jqWindowOrigin = jqWindowOrigin || ( function(){\r
2258                                                 return $( $( '#windowTemplete').remove().html());\r
2259                                         })();\r
2260                                         closeButtonWidth = closeButtonWidth || ( function(){\r
2261                                                 return h2c.util.getElementSize( jqWindowOrigin.clone( true).find( '.window-close-button').get( 0)).width;\r
2262                                         })();\r
2263                                         \r
2264                                         jqStage = jqEditor;\r
2265                                         this.$ = jqWrapper = jqWindowOrigin.clone( true);\r
2266                                         jqHeader = jqWrapper.children( '.window-header').eq( 0).html( title);\r
2267                                         headerH = h2c.util.getElementSize( jqHeader.get( 0)).height;\r
2268                                         elmBody = jqWrapper.children( '.window-body').get( 0);\r
2269                                         elmBodyStyle = elmBody.style;\r
2270                                         if( bodyTempleteID) {\r
2271                                                 jqWrapper.find( '.window-body-insert-position').replaceWith( $( $( '#' +bodyTempleteID).remove().html()));\r
2272                                         } else {\r
2273                                                 jqWrapper.find( '.window-body-insert-position').remove();\r
2274                                         }\r
2275                                         CLOSE_BUTTON_ENABLED !== true && jqWrapper.find( '.window-close-button').remove();\r
2276                                         \r
2277                                         this.onInit && this.onInit();\r
2278                                         delete this.init;\r
2279                                 },\r
2280                                 x: function(){ return x;},\r
2281                                 y: function(){ return y;},\r
2282                                 w: function(){ return w;},\r
2283                                 h: function(){ return h;},\r
2284                                 $: null,\r
2285                                 title: function( _title){\r
2286                                         _title !== undefined && jqHeader.html( _title);\r
2287                                         title = _title || title;\r
2288                                         return title;\r
2289                                 },\r
2290                                 visible: visible,\r
2291                                 firstOpen: function(){\r
2292                                         if( RESIZE_BUTTON_ENABLED === true){\r
2293                                                 jqWrapper.find( '.window-resize-button').eq( 0).mousedown( onWindowResize);\r
2294                                         } else {\r
2295                                                 jqWrapper.find( '.window-resize-button').remove();\r
2296                                         }\r
2297                                         update( x, y, w, h);\r
2298                                         \r
2299                                         this.onFirstOpen && this.onFirstOpen();\r
2300                                         \r
2301                                         delete this.firstOpen;\r
2302                                 },\r
2303                                 open: function(){\r
2304                                         if( visible === true) return;\r
2305                                         instance.visible = visible = true;\r
2306                                         openWindow( instance);\r
2307                                         MENUBAR_SELWCTION.title( 'hide ' +title);\r
2308                                         \r
2309                                         for( var i=0, l = WINDOW_ARRAY.length; i<l; ++i){\r
2310                                                 if( WINDOW_ARRAY[ i] === instance){\r
2311                                                         WINDOW_ARRAY.splice( i, 1);\r
2312                                                         WINDOW_ARRAY.unshift( instance);\r
2313                                                         currentWindow = null;\r
2314                                                         currentWindowIndex = -1;\r
2315                                                 }\r
2316                                         }\r
2317                                 },\r
2318                                 close: function(){\r
2319                                         if( visible === false) return;\r
2320                                         instance.visible = visible = false;\r
2321                                         instance.onClose && setTimeout( instance.onClose, 0);\r
2322                                         closeWindow( instance);\r
2323                                         MENUBAR_SELWCTION.title( 'show ' +title);\r
2324                                 },\r
2325                                 bodyBackOrForward: bodyBackOrForward,\r
2326                                 onMouseDown: function( _mouseX, _mouseY){\r
2327                                         if( x > _mouseX || y > _mouseY || x +w < _mouseX || y +headerH < _mouseY ) return;\r
2328                                         if( CLOSE_BUTTON_ENABLED === true && x +w -closeButtonWidth < _mouseX){\r
2329                                                 this.close();\r
2330                                                 return;\r
2331                                         }\r
2332                                         isDragging = true;\r
2333                                         MOUSE_CURSOR( 'move');                          \r
2334                                         startX = x;\r
2335                                         startY = y;\r
2336                                         startW = w;\r
2337                                         startH = h;\r
2338                                         xOffset = _mouseX;\r
2339                                         yOffset = _mouseY;\r
2340                                 },\r
2341                                 onMouseUp: function( _mouseX, _mouseY){\r
2342                                         isDragging = isResizing = false;\r
2343                                         MOUSE_CURSOR( '');\r
2344                                 },\r
2345                                 onMouseMove: function( _mouseX, _mouseY){\r
2346                                         var _updateX = _mouseX -xOffset,\r
2347                                                 _updateY = _mouseY -yOffset;\r
2348                                         \r
2349                                         if( isResizing === true){\r
2350                                                 var _w = startW +_updateX,\r
2351                                                         _h = startH +_updateY;\r
2352                                                 update( startX, startY, _w < minWindowW ? minWindowW : _w, _h < minWindowH ? minWindowH : _h);\r
2353                                                 return;\r
2354                                         } else\r
2355                                         if( isDragging === true) {\r
2356                                                 update( startX +_updateX, startY +_updateY);\r
2357                                                 return;\r
2358                                         } else\r
2359                                         if( x > _mouseX || x +w < _mouseX ) return;\r
2360         \r
2361                                         ( y <= _mouseY && y +headerH >= _mouseY ) ?\r
2362                                                 MOUSE_CURSOR( 'pointer') :      // hit to header\r
2363                                                 MOUSE_CURSOR( '');\r
2364                                         bodyBackOrForward( y +headerH > _mouseY || y +headerH +bodyH < _mouseY);\r
2365                                 },\r
2366                                 onMouseOut: function( _mouseX, _mouseY){\r
2367                                         bodyIsTachable === true && bodyBackOrForward( true);\r
2368                                         isDragging = false;\r
2369                                         MOUSE_CURSOR( '');\r
2370                                 },\r
2371                                 busy: function(){\r
2372                                         return isDragging === true || isResizing === true;\r
2373                                 },\r
2374                                 bodyHeight: function(){\r
2375                                         return  bodyH;\r
2376                                 }\r
2377                         }\r
2378                 };\r
2379                 \r
2380                 function getCurrentWindow( _mouseX, _mouseY){\r
2381                         if( currentWindow && currentWindow.busy() === true) return currentWindowIndex;\r
2382                         var l = WINDOW_ARRAY.length,\r
2383                                 _currentWindow = null,\r
2384                                 _win, _x, _y;\r
2385                         currentWindowIndex = -1;\r
2386                         for( var i=0; i<l; i++){\r
2387                                 _win = WINDOW_ARRAY[ i];\r
2388                                 if( _win.visible !== true) continue;\r
2389                                 _x = _win.x();\r
2390                                 _y = _win.y();\r
2391                                 if( _x <= _mouseX && _y <= _mouseY && _x +_win.w() >= _mouseX && _y +_win.h() >= _mouseY){\r
2392                                         _currentWindow = _win;\r
2393                                         currentWindowIndex = i;\r
2394                                         break;\r
2395                                 }\r
2396                         }\r
2397                         currentWindow && currentWindow !== _currentWindow && currentWindow.onMouseOut( _mouseX, _mouseY);\r
2398                         currentWindow = _currentWindow;\r
2399                         return currentWindowIndex;\r
2400                 }\r
2401                 function openWindow( _window){\r
2402                         if( _window.visible !== true) return;\r
2403                         var _jqWindow = _window.$;\r
2404                         jqContainer.append( _jqWindow);// appendした後に fadeIn() しないと ie で filterが適用されない.\r
2405                         _jqWindow.fadeIn(\r
2406                                 function(){\r
2407                                         _window.firstOpen && _window.firstOpen();\r
2408                                         _window.onOpen && setTimeout( _window.onOpen, 0);\r
2409                                 }\r
2410                         );\r
2411                         return;\r
2412                 }\r
2413                 function closeWindow( _window){\r
2414                         if( _window.visible !== false) return;\r
2415                         var l = WINDOW_ARRAY.length;\r
2416                         for( var i=0; i<l; ++i){\r
2417                                 if( WINDOW_ARRAY[ i] === _window){\r
2418                                         //WINDOW_ARRAY.splice( i, 1);\r
2419                                         //WINDOW_ARRAY.push( _window);\r
2420                                         _window.$.stop().fadeOut( function(){\r
2421                                                 this.parentNode.removeChild( this);\r
2422                                         });\r
2423                                         return;\r
2424                                 }\r
2425                         }\r
2426                 }\r
2427                 \r
2428                 return {\r
2429                         init: function(){\r
2430                                 jqContainer = $( '#window-container');\r
2431                                 \r
2432                                 var l = WINDOW_ARRAY.length,\r
2433                                         _window;\r
2434                                 for( var i=l-1; i >= 0; --i){\r
2435                                         _window = WINDOW_ARRAY[ i];\r
2436                                         _window.init && _window.init( jqContainer);\r
2437                                         _window.visible === true && openWindow( _window);\r
2438                                 }\r
2439                                 log = $( '#window-log');\r
2440                                 \r
2441                                 delete WINDOWS_CONTROL.init;\r
2442                         },\r
2443                         onMouseMove: function( _mouseX, _mouseY){\r
2444                                 var _index = getCurrentWindow( _mouseX, _mouseY);\r
2445                                 if( _index === 0){\r
2446                                         currentWindow.onMouseMove( _mouseX, _mouseY);\r
2447                                         return true;\r
2448                                 } else\r
2449                                 if( _index !== -1){ // 先頭のクリックでない場合\r
2450                                 // Array を前に\r
2451                                         WINDOW_ARRAY.splice( currentWindowIndex, 1);\r
2452                                         WINDOW_ARRAY.unshift( currentWindow);\r
2453                                 // Domを最後に\r
2454                                         jqContainer.append( currentWindow.$);\r
2455                                         currentWindowIndex = 0;\r
2456                                         return true;\r
2457                                 }\r
2458                                 return false;\r
2459                         },\r
2460                         onMouseUp: function( _mouseX, _mouseY){\r
2461                                 if( getCurrentWindow( _mouseX, _mouseY) === 0){\r
2462                                         currentWindow.onMouseUp( _mouseX, _mouseY);\r
2463                                         return true;\r
2464                                 }\r
2465                                 return false;\r
2466                         },\r
2467                         onMouseDown: function( _mouseX, _mouseY){\r
2468                                 if( getCurrentWindow( _mouseX, _mouseY) === 0){\r
2469                                         currentWindow.onMouseDown( _mouseX, _mouseY);\r
2470                                         return true;\r
2471                                 }\r
2472                                 return false;\r
2473                         },\r
2474                         onMouseClick: function( _mouseX, _mouseY){\r
2475                                 return false;\r
2476                         },\r
2477                         busy: function(){\r
2478                                 return currentWindow !== null;\r
2479                         },\r
2480                         onWindowResize: function( _windowW, _windowH){\r
2481                                 /*\r
2482                                  * 画面外に出るwindowの移動\r
2483                                  */\r
2484                         },\r
2485                         createWindow: function( scope, EXTENDS, bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeButtonEnabled, opt_resizeButtonEnabled, opt_minWindowW, opt_minWindowH){\r
2486                                 opt_visible = opt_visible !== false;\r
2487                                 opt_closeButtonEnabled = opt_closeButtonEnabled === true;\r
2488                                 opt_resizeButtonEnabled = opt_resizeButtonEnabled === true;\r
2489                                 opt_minWindowW = opt_minWindowW || ( w < DEFAULT_MIN_WINDOW_WIDTH) ? w : DEFAULT_MIN_WINDOW_WIDTH;\r
2490                                 opt_minWindowH = opt_minWindowH || ( h < DEFAULT_MIN_WINDOW_HEIGHT) ? h : DEFAULT_MIN_WINDOW_HEIGHT;\r
2491                                 \r
2492                                 var _window = h2c.util.extend(\r
2493                                         WindowClass.apply( scope, [ bodyTempleteID, title, x, y, w, h, opt_visible, opt_closeButtonEnabled, opt_resizeButtonEnabled, opt_minWindowW, opt_minWindowH]),\r
2494                                         EXTENDS\r
2495                                 );\r
2496                                 WINDOW_ARRAY.unshift( _window);\r
2497                                 WINDOWS_CONTROL.init === undefined && _window.init( jqContainer);\r
2498                                 WINDOWS_CONTROL.init === undefined && openWindow( _window);\r
2499                                 return _window;\r
2500                         }\r
2501                 }\r
2502         })();\r
2503 \r
2504 /* ----------------------------------------\r
2505  * TOOL_BOX_WINDOW\r
2506  */\r
2507         var TOOL_BOX_WINDOW = ( function(){\r
2508                 var addImageButton, addTextButton, editBgButton, switchGridButton, popupHelpButton, postButton,\r
2509                         gridSwitchFunction,\r
2510                         instance;\r
2511                         \r
2512                 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 73, false, true, addImage);\r
2513                 MENU_BAR_CONTROL.EDIT.createSelection( 'Add Image', 'ctrl + I', addImage, true, true, false);\r
2514                 \r
2515                 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 84, false, true, addText);\r
2516                 MENU_BAR_CONTROL.EDIT.createSelection( 'Add Text', 'ctrl + T', addText, true, false, true);\r
2517 \r
2518                 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 71, false, true, switchGrid);\r
2519                 MENU_BAR_CONTROL.EDIT.createSelection( 'show Grid', 'ctrl + G', switchGrid, true, true, true);\r
2520 \r
2521                 function addImage( e){\r
2522                         setTimeout( CANVAS_CONTROL.createImageElement, 0);\r
2523                         e && e.preventDefault();\r
2524                         return false;\r
2525                 }\r
2526                 function addText( e){\r
2527                         setTimeout( CANVAS_CONTROL.createTextElement, 0);\r
2528                         e && e.preventDefault();\r
2529                         return false;\r
2530                 }\r
2531                 function switchGrid( e){\r
2532                         setTimeout( gridSwitchFunction, 0);\r
2533                         e && e.preventDefault();\r
2534                         return false;\r
2535                 }\r
2536                 function popupHelp( e){\r
2537                         instance.bodyBackOrForward( true);\r
2538                         setTimeout( HELP_DOCUMENTS_WINDOW.open, 0); // setTimeout で囲むと window が開かない\r
2539                         e && e.preventDefault();\r
2540                         return false;\r
2541                 }\r
2542                 function editBG( e){\r
2543                         instance.bodyBackOrForward( true);\r
2544                         setTimeout( INFOMATION_WINDOW.open, 0); \r
2545                         e && e.preventDefault();\r
2546                         return false;\r
2547                 }\r
2548                 \r
2549                 return WINDOWS_CONTROL.createWindow(\r
2550                         this,\r
2551                         {\r
2552                                 onInit: function(){\r
2553                                         instance = this;\r
2554                                         delete this.onInit;\r
2555                                 },\r
2556                                 onFirstOpen: function(){\r
2557                                         addImageButton = $( '#toolbox-add-image-button').click( addImage);\r
2558                                         addTextButton = $( '#toolbox-add-text-button').click( addText);\r
2559                                         editBgButton = $( '#toolbox-edit-bg-button').click( editBG);\r
2560                                         switchGridButton = $( '#toolbox-switch-grid').click( switchGrid);\r
2561                                         popupHelpButton = $( '#toolbox-popup-help-button').click( popupHelp);\r
2562                                         \r
2563                                         postButton = $( '#toolbox-post-button');\r
2564                                         \r
2565                                         delete this.onFirstOpen;\r
2566                                 },\r
2567                                 setGridSwitchFunction: function( _gridSwitchFunction){\r
2568                                         gridSwitchFunction = _gridSwitchFunction || gridSwitchFunction;\r
2569                                 }\r
2570                         },\r
2571                         'toolbox-window', 'Tool box', 0, 215, 110, 290, true\r
2572                 );\r
2573         })();\r
2574 /* ----------------------------------------\r
2575  * INFOMATION_WINDOW\r
2576  */                     \r
2577         var INFOMATION_WINDOW = ( function(){\r
2578                 var FADE_EFFECT_ENABLED = h2c.isIE === false || h2c.ieVersion >= 8,\r
2579                         FADE_IN_EFFECT = FADE_EFFECT_ENABLED === true ? 'fadeIn' : 'show',\r
2580                         FADE_OUT_EFFECT = FADE_EFFECT_ENABLED === true ? 'fadeOut' : 'hide',\r
2581                         backgroundInfomationElm,\r
2582                         jqComicElementInformation,\r
2583                         elmValueX, elmValueY, elmValueZ, elmValueA, elmValueW, elmValueH, elmAspect,\r
2584                         elmPercentW, elmPercentH,\r
2585                         currentComicElement = null,\r
2586                         currentElementType = -1;\r
2587 \r
2588                 return WINDOWS_CONTROL.createWindow(\r
2589                         this,\r
2590                         {\r
2591                                 onFirstOpen: function(){\r
2592                                         backgroundInfomationElm = $( '#panel-background-information');\r
2593                                         \r
2594                                         jqComicElementInformation = $( '#comic-element-infomation').hide().css( {\r
2595                                                 height:         this.bodyHeight()\r
2596                                         });\r
2597                                         var TAB_GROUP_ID = 'comic-element-attribute';\r
2598                                         var CREATER = h2c.key.createEditableText;\r
2599                                         elmValueX = CREATER( $( '#comic-element-x'), null, TAB_GROUP_ID);\r
2600                                         elmValueY = CREATER( $( '#comic-element-y'), null, TAB_GROUP_ID);\r
2601                                         elmValueZ = CREATER( $( '#comic-element-z'), null, TAB_GROUP_ID);\r
2602                                         elmValueA = CREATER( $( '#comic-element-a'), null, TAB_GROUP_ID);\r
2603                                         elmValueW = CREATER( $( '#comic-element-w'), null, TAB_GROUP_ID);\r
2604                                         elmValueH = CREATER( $( '#comic-element-h'), null, TAB_GROUP_ID);\r
2605                                         elmPercentW = CREATER( $( '#comic-element-w-percent'), null, TAB_GROUP_ID);\r
2606                                         elmPercentH = CREATER( $( '#comic-element-h-percent'), null, TAB_GROUP_ID);\r
2607                                         elmAspect = $( '#comic-element-keep-aspect');\r
2608                                         delete this.onFirstOpen;\r
2609                                 },\r
2610                                 onResize: function( w, h){\r
2611                                         jqComicElementInformation && jqComicElementInformation.css( {\r
2612                                                 height: this.bodyHeight()\r
2613                                         });\r
2614                                 },\r
2615                                 update: function( _elementType, x, y, z, a, w, h, wPercent, hPercent, keepAspect){\r
2616                                         if( !backgroundInfomationElm) return; // なぜか !backgroundInfomationElm が必要\r
2617                                         if( currentElementType !== _elementType){\r
2618                                                 if( _elementType !== -1){\r
2619                                                         if( _elementType === 1){\r
2620                                                                 elmValueA.show();\r
2621                                                                 elmPercentW.hide();\r
2622                                                                 elmPercentH.hide();\r
2623                                                                 elmAspect.hide();\r
2624                                                         } else {\r
2625                                                                 elmValueA.hide();\r
2626                                                                 elmPercentW.show();\r
2627                                                                 elmPercentH.show();\r
2628                                                                 elmAspect.show();\r
2629                                                         }\r
2630                                                         currentElementType === -1 && jqComicElementInformation.stop().css( {\r
2631                                                                 filter:         '',\r
2632                                                                 opacity:        ''\r
2633                                                         })[ FADE_IN_EFFECT]();\r
2634                                                 } else {\r
2635                                                         currentElementType !== -1 && jqComicElementInformation.stop().css({\r
2636                                                                 filter:         '',\r
2637                                                                 opacity:        ''\r
2638                                                         })[ FADE_OUT_EFFECT]();\r
2639                                                 }\r
2640                                                 currentElementType = _elementType;\r
2641                                         }\r
2642                                         if( currentElementType !== -1){\r
2643                                                 elmValueX.update( x);\r
2644                                                 elmValueY.update( y);\r
2645                                                 elmValueZ.update( z);\r
2646                                                 _elementType === 1 && elmValueA.update( a);\r
2647                                                 elmValueW.update( w);\r
2648                                                 elmValueH.update( h);\r
2649                                                 _elementType === 0 && elmPercentW.update( wPercent);\r
2650                                                 _elementType === 0 && elmPercentH.update( hPercent);                                    \r
2651                                         } else {\r
2652                                                 \r
2653                                         }\r
2654                                 }\r
2655                         },\r
2656                         'infomation-window', 'Infomation', 0, 30, 200, 180, true\r
2657                 );\r
2658         })();\r
2659 \r
2660 /* ----------------------------------------\r
2661  * HELP_WINDOW\r
2662  */\r
2663         var HELP_DOCUMENTS_WINDOW = ( function(){\r
2664                 var visible = true,\r
2665                         hasAjaxContents = false,\r
2666                         jqAjaxContents,\r
2667                         jqNaviItems,\r
2668                         jqPages,\r
2669                         HELP = MENU_BAR_CONTROL.HELP,\r
2670                         onLoadFunction = HELP.createAjaxSelection( onFirstOpen),\r
2671                         instance;\r
2672                 function jumpPage( _index){\r
2673                         \r
2674                 }\r
2675                 function onFirstOpen( _pageIndex){\r
2676                         _pageIndex = _pageIndex || 0;\r
2677                         if( hasAjaxContents === false){\r
2678                                 $.ajax({\r
2679                                         url:            'help/jp.xml',\r
2680                                         dataType:       'xml',\r
2681                                         success:        function( _xml){\r
2682                                                 var jqXML = $( _xml),\r
2683                                                         helpTitle = jqXML.find( 'pages').eq( 0).attr( 'title'),\r
2684                                                         elmNavi = document.createElement( 'DIV'),\r
2685                                                         elmItemOrigin = document.createElement( 'A'),\r
2686                                                         elmPages = document.createElement( 'DIV'),\r
2687                                                         elmPageOrigin = document.createElement( 'DIV'),\r
2688                                                         elmTitleOrigin = document.createElement( 'H2'),\r
2689                                                         elmPage,\r
2690                                                         numPage = 0;\r
2691                                                 elmNavi.className = 'sidenavi';\r
2692                                                 elmItemOrigin.className = 'sidenavi-item';\r
2693                                                 elmItemOrigin.href = '#';\r
2694                                                 elmPages.className = 'page-contents';\r
2695                                                 elmPageOrigin.className = 'page-content';\r
2696                                                 elmPageOrigin.appendChild( elmTitleOrigin);\r
2697                                                 \r
2698                                                 // helpTitle && instance.title( helpTitle);\r
2699                                                 \r
2700                                                 jqXML.find( 'page').each( function(){\r
2701                                                         var xmlPage = $( this),\r
2702                                                                 title = xmlPage.attr( 'title'),\r
2703                                                                 content = xmlPage.text();\r
2704                                                         \r
2705                                                         elmItemOrigin.innerHTML = title;\r
2706                                                         elmNavi.appendChild( elmItemOrigin.cloneNode( true));\r
2707                                                         \r
2708                                                         elmTitleOrigin.innerHTML = title;\r
2709                                                         elmPage = elmPageOrigin.cloneNode( true);\r
2710                                                         elmPage.innerHTML = content;\r
2711                                                         \r
2712                                                         h2c.util.cleanElement( elmPage);\r
2713                                                         \r
2714                                                         if( elmPage.childNodes.length > 0){\r
2715                                                                 elmPage.insertBefore( elmTitleOrigin.cloneNode( true), elmPage.childNodes[0]);\r
2716                                                         } else {\r
2717                                                                 elmPage.appendChild( elmTitleOrigin.cloneNode( true));\r
2718                                                         }\r
2719                                                         elmPages.appendChild( elmPage);\r
2720                                                         \r
2721                                                         HELP.createSelection( title, null, ( function( _pageIndex){\r
2722                                                                 return function(){\r
2723                                                                         HELP_DOCUMENTS_WINDOW.open();\r
2724                                                                         onOpen( _pageIndex);                                                                    \r
2725                                                                 }\r
2726                                                         })( numPage), true);\r
2727                                                         ++numPage;\r
2728                                                 });\r
2729                                                 onLoadFunction();\r
2730                                                 onLoadFunction = null;\r
2731                                                 \r
2732                                                 jqAjaxContents.removeClass( 'loading').append( elmNavi, elmPages);\r
2733                                                 \r
2734                                                 jqNaviItems = jqAjaxContents.find( 'a.' +elmItemOrigin.className)\r
2735                                                         .click( function( e){\r
2736                                                                 var that = this,\r
2737                                                                         parent = this.parentNode,\r
2738                                                                         i = ( function(){\r
2739                                                                                 var children = parent.getElementsByTagName( 'A'),\r
2740                                                                                         l = children.length;\r
2741                                                                                 for( var i=0; i<l; ++i){\r
2742                                                                                         if( children[ i] === that) return i;\r
2743                                                                                 }\r
2744                                                                                 return -1;\r
2745                                                                         })();\r
2746                                                                 e.stopPropagation();\r
2747                                                                 if( i === -1) return false;\r
2748                                                                 jqNaviItems.removeClass( 'current').eq( i).addClass( 'current');\r
2749                                                                 jqPages.hide().eq( i).show();\r
2750                                                                 \r
2751                                                                 return false;\r
2752                                                         });\r
2753                                                 jqAjaxContents.find( '.' +elmPageOrigin.className).find( 'a')\r
2754                                                         .click( function( e){\r
2755                                                                 var that = this,\r
2756                                                                         i = ( function(){\r
2757                                                                                 var href = that.href,\r
2758                                                                                         i = href.split( '#jump'),\r
2759                                                                                         n = i[1]\r
2760                                                                                 if( n && '' +parseFloat( n) === n){\r
2761                                                                                         return parseFloat( n)\r
2762                                                                                 }\r
2763                                                                                 return -1;\r
2764                                                                         })();\r
2765                                                                 e.stopPropagation();\r
2766                                                                 if( i === -1) return false;\r
2767                                                                 jqNaviItems.removeClass( 'current').eq( i).addClass( 'current');\r
2768                                                                 jqPages.hide().eq( i).show();\r
2769                                                                 \r
2770                                                                 return false;\r
2771                                                         });\r
2772                                                 jqNaviItems.eq( _pageIndex).addClass( 'current');\r
2773                                                 jqPages = jqAjaxContents.find( '.page-content');\r
2774                                                 jqPages.eq( _pageIndex).show();\r
2775                                         }\r
2776                                 });\r
2777                                 hasAjaxContents = true;\r
2778                         }\r
2779                         function onOpen( _pageIndex){\r
2780                                 _pageIndex = _pageIndex || 0;\r
2781                                 jqNaviItems.removeClass( 'current').eq( _pageIndex).addClass( 'current');\r
2782                                 jqPages.hide().eq( _pageIndex).show();\r
2783                         }\r
2784                 }\r
2785                 return WINDOWS_CONTROL.createWindow(\r
2786                         this,\r
2787                         {\r
2788                                 onInit: function(){\r
2789                                         instance = this;\r
2790                                         jqAjaxContents = this.$.find( '.window-body').addClass( 'loading').css( { height: this.bodyHeight()});\r
2791                                         delete this.onInit;\r
2792                                 },\r
2793                                 onFirstOpen: onFirstOpen,\r
2794                                 onResize: function( w, h){\r
2795                                         jqAjaxContents && jqAjaxContents.css( { height: this.bodyHeight()});\r
2796                                 },\r
2797                                 setAjaxContent: function( html){\r
2798                                         \r
2799                                         delete this.onLoadAjaxContent;\r
2800                                 }\r
2801                         },\r
2802                         null, 'Help', 0, 215, 400, 350, false, true, true, 300, 300\r
2803                 );\r
2804         })();\r
2805 \r
2806 /* ----------------------------------------\r
2807  *    - CANVAS_CONTROL\r
2808  *       - GRID_CONTROL\r
2809  *       - WHITE_GLASS_CONTROL\r
2810  *       - PANEL_BORDER_CONTROL\r
2811  *       - COMIC_ELEMENT_CONTROL\r
2812  *          - PanelResizerClass\r
2813  *          - COMIC_ELEMENT_OPERATOR\r
2814  *          - ImageElementClass\r
2815  *          - TextElementClass\r
2816  */     \r
2817         var CANVAS_CONTROL = ( function(){\r
2818                 var DEFAULT_PANEL_WIDTH = 400,\r
2819                         DEFAULT_PANEL_HEIGHT = 300,\r
2820                         MIN_PANEL_HEIGHT = 20,\r
2821                         BORDER_WIDTH = 2,\r
2822                         RESIZER_BORDER_WIDTH = 1,\r
2823                         SPACE_ENABLED = h2c.key.spaceEnabled,\r
2824                         canvasW, canvasH, canvasX, canvasY,\r
2825                         xOffset, yOffset, startCanvasX, startCanvasY,\r
2826                         isDragging = false,\r
2827                         isCanvasDraggble = false;\r
2828                 \r
2829                 var GRID_CONTROL = ( function(){\r
2830                         var elmGrid = document.getElementById( 'grid'),\r
2831                                 jQGrid,\r
2832                                 visible = false;\r
2833                         \r
2834                         function update(){\r
2835                                 jQGrid.css( {\r
2836                                         opacity:        '',\r
2837                                         fliter:         ''\r
2838                                 }).stop()[ visible === true ? 'fadeOut' : 'fadeIn']();\r
2839                                 visible = !visible;\r
2840                                 if( visible === true){\r
2841                                         elmGrid.style.backgroundImage = "url('grid.gif')";\r
2842                                 }\r
2843                                 return visible;\r
2844                         }\r
2845                         return {\r
2846                                 init: function(){\r
2847                                         jQGrid = $( elmGrid);\r
2848                                         this.resize();\r
2849                                         TOOL_BOX_WINDOW.setGridSwitchFunction( update);\r
2850                                         delete GRID_CONTROL.init;\r
2851                                 },\r
2852                                 resize: function(){\r
2853                                         elmGrid.style.backgroundPosition = [ canvasX % 10, 'px ', canvasY % 10, 'px'].join( '');\r
2854                                         elmGrid.style.height = windowH +'px';                           \r
2855                                 },\r
2856                                 enabled: function(){\r
2857                                         return visible;\r
2858                                 }\r
2859                         }\r
2860                 })();\r
2861                 \r
2862         /*\r
2863          *      WHITE_GLASS_CONTROL\r
2864          */     \r
2865                 var WHITE_GLASS_CONTROL = ( function(){\r
2866                         var styleTop = document.getElementById( 'whiteGlass-top').style,\r
2867                                 styleLeft = document.getElementById( 'whiteGlass-left').style,\r
2868                                 styleRight = document.getElementById( 'whiteGlass-right').style,\r
2869                                 styleBottom = document.getElementById( 'whiteGlass-bottom').style;\r
2870                         function resize(){\r
2871                                 var     _w = canvasW,\r
2872                                         _h = canvasH,\r
2873                                         marginTop = canvasY,\r
2874                                         marginBottom = windowH -_h -marginTop,\r
2875                                         marginX = canvasX,\r
2876                                         rightWidth = windowW -_w -marginX;\r
2877                                 \r
2878                                 styleTop.height = ( marginTop < 0 ? 0 : marginTop) +'px';\r
2879                                 \r
2880                                 styleLeft.top = marginTop +'px';\r
2881                                 styleLeft.width = ( marginX < 0 ? 0 : marginX) +'px';\r
2882                                 styleLeft.height = ( _h + marginBottom) +'px';\r
2883                                 \r
2884                                 styleRight.top = marginTop +'px';\r
2885                                 styleRight.left = _w +marginX +'px';\r
2886                                 styleRight.width = ( rightWidth < 0 ? 0 : rightWidth) +'px';\r
2887                                 styleRight.height = ( _h + marginBottom) +'px';\r
2888                                 \r
2889                                 styleBottom.top = ( _h +marginTop) +'px';\r
2890                                 styleBottom.left = marginX +'px';\r
2891                                 styleBottom.width = _w +'px';\r
2892                                 styleBottom.height = ( marginBottom < 0 ? 0 : marginBottom) +'px';\r
2893                         }\r
2894                         return {\r
2895                                 resize: resize\r
2896                         }\r
2897                 })();\r
2898 \r
2899         /*\r
2900          * PANEL_BORDER_CONTROL\r
2901          */\r
2902                 var PANEL_BORDER_CONTROL = ( function(){\r
2903                         var     panelElm, borderWidth;\r
2904                         \r
2905                         function resize(){\r
2906                                 panelElm.css( {\r
2907                                         left:   canvasX -BORDER_WIDTH,\r
2908                                         top:    canvasY -BORDER_WIDTH,\r
2909                                         width:  canvasW,\r
2910                                         height: canvasH\r
2911                                 });\r
2912                         }\r
2913                                                 \r
2914                         return {\r
2915                                 init: function(){\r
2916                                         panelElm = $( '#panel-border');\r
2917                                         borderWidth = panelElm.css( 'border-width');\r
2918                                         \r
2919                                         delete PANEL_BORDER_CONTROL.init;\r
2920                                 },\r
2921                                 resize: resize\r
2922                         }\r
2923                 })();\r
2924         \r
2925         /*\r
2926          * COMIC_ELEMENT_CONTROL\r
2927          *   - PanelResizerClass\r
2928          *   - COMIC_ELEMENT_OPERATOR\r
2929          *   - ImageElementClass\r
2930          *   - TextElementClass\r
2931          */\r
2932                 var COMIC_ELEMENT_CONTROL = ( function( _onResizeFunction){\r
2933                         var     MIN_OBJECT_SIZE = 19,\r
2934                                 log,\r
2935                                 currentElement = null,\r
2936                                 _canvasX, _canvasY, _canvasW, _canvasH,\r
2937                                 MOUSE_HIT_AREA = 10,\r
2938                                 SAVE = HISTORY.saveState;\r
2939                 /*\r
2940                  * --------------------------------------------------------------------------------------------\r
2941                  * panel resizer\r
2942                  */\r
2943                         var PanelResizerClass = function( ELM, onPanelResizeFunction, isTop){\r
2944                                 var     BORDER_WIDTH = 2,\r
2945                                         yOffset, y, _canvasY, _canvasH,\r
2946                                         RESIZER_HEIGHT = 30,\r
2947                                         isDragging = false,\r
2948                                         SAVE = HISTORY.saveState,\r
2949                                         MOUSE_CURSOR = updateMouseCursor;\r
2950                                         \r
2951                                 function restoreState( arg){\r
2952                                         if( arg && arg.length > 3){\r
2953                                                 canvasX = arg[ 0] || canvasX;\r
2954                                                 canvasY = arg[ 1] || canvasY;\r
2955                                                 canvasW = arg[ 2] || canvasW;\r
2956                                                 canvasH = arg[ 3] || canvasH;\r
2957                                                 onPanelResizeFunction( isTop);\r
2958                                         }\r
2959                                 }\r
2960                                         \r
2961                                 return {\r
2962                                         init: function( _elm){\r
2963                                                 this.$ = $( ELM);\r
2964                                                 ELM.style.width = ( canvasW +2)+'px';\r
2965                                         },\r
2966                                         $: null,\r
2967                                         hitareaX: function(){ return -1;},\r
2968                                         hitareaY: function(){ return isTop === true ? ( -35 -BORDER_WIDTH) : ( canvasH +5 +BORDER_WIDTH);},\r
2969                                         hitareaW: function(){ return canvasW +2;},\r
2970                                         hitareaH: function(){ return RESIZER_HEIGHT;},\r
2971                                         resize: resize,\r
2972                                         busy: function(){\r
2973                                                 return isDragging;\r
2974                                         },\r
2975                                         onMouseDown: function( _mouseX, _mouseY){\r
2976                                                 yOffset = _mouseY;\r
2977                                                 _canvasY = canvasY;\r
2978                                                 _canvasH = canvasH;\r
2979                                                 isDragging = true;\r
2980                                         },\r
2981                                         onMouseMove: function( _mouseX, _mouseY){\r
2982                                                 if( isDragging !== true){\r
2983                                                         COMIC_ELEMENT_OPERATOR.hide();\r
2984                                                         MOUSE_CURSOR( 'n-resize');\r
2985                                                 } else {\r
2986                                                         var move = _mouseY -yOffset;\r
2987                                                         if( isTop === true){    \r
2988                                                                 //if( 0 < _canvasH - move){\r
2989                                                                         if( _canvasH - move < MIN_PANEL_HEIGHT){\r
2990                                                                                 move = _canvasH -MIN_PANEL_HEIGHT;\r
2991                                                                         }\r
2992                                                                         canvasY = _canvasY +move;\r
2993                                                                         canvasH = _canvasH -move;\r
2994                                                                         log.html( move)\r
2995                                                                         onPanelResizeFunction( true);\r
2996                                                                 //}                                                             \r
2997                                                         } else {\r
2998                                                                 var _h = _canvasH +move;\r
2999                                                                 if( 0 < _h && _h < windowH -canvasY -RESIZER_HEIGHT -5 -BORDER_WIDTH){\r
3000                                                                         if( _h < MIN_PANEL_HEIGHT){\r
3001                                                                                 _h = MIN_PANEL_HEIGHT;\r
3002                                                                         }\r
3003                                                                         canvasH = _h;\r
3004                                                                         onPanelResizeFunction( false);\r
3005                                                                 }\r
3006                                                         }\r
3007                                                 }\r
3008                                         },\r
3009                                         onMouseUp: function( _mouseX, _mouseY){\r
3010                                                 ( _canvasY !== canvasY || _canvasH !== canvasH) && SAVE( restoreState, [ NaN, _canvasY, NaN, _canvasH], [ NaN, canvasY, NaN, canvasH]);\r
3011                                                 isDragging = false;\r
3012                                         }\r
3013                                 }\r
3014                         };\r
3015                         \r
3016                         var     PANEL_RESIZER_TOP = PanelResizerClass.apply( {}, [ document.getElementById( 'panel-resizer-top'), _onResizeFunction, true]),\r
3017                                 PANEL_RESIZER_BOTTOM = PanelResizerClass.apply( {}, [ document.getElementById( 'panel-resizer-bottom'), _onResizeFunction, false]),\r
3018                                 DRAGGABLE_ELEMENT_ARRAY = [ PANEL_RESIZER_TOP, PANEL_RESIZER_BOTTOM],\r
3019                                 NUM_RESIZER = DRAGGABLE_ELEMENT_ARRAY.length;\r
3020                         \r
3021                         _onResizeFunction = PanelResizerClass = undefined;\r
3022                 \r
3023                 /*\r
3024                  * --------------------------------------------------------------------------------------------\r
3025                  * COMIC_ELEMENT_OPERATOR\r
3026                  */\r
3027                         var COMIC_ELEMENT_OPERATOR = ( function(){\r
3028                                 var     MOUSE_CURSOR = updateMouseCursor,\r
3029                                         SAVE = HISTORY.saveState,\r
3030                                         INFOMATION = INFOMATION_WINDOW.update,\r
3031                                         GRID_ENABLED = GRID_CONTROL.enabled,\r
3032                                         HIT_AREA = MOUSE_HIT_AREA,\r
3033                                         currentIsTextElement = false,\r
3034                                         currentControler = null,\r
3035                                         currentElement = null,\r
3036                                         x, y, w, h, angle, flipV, flipH,\r
3037                                         COMIC_ELEMENT_CONSOLE = ( function(){\r
3038                                                 var LAYER_BACK_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'layer back', 'ctrl + B', layerBack, false, true, false),\r
3039                                                         LAYER_FORWARD_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'layer forward', 'ctrl + F', layerForward, false, false, false),\r
3040                                                         DELETE_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'delete', 'ctrl + D', del, false, true, true),\r
3041                                                         EDIT_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'Edit Text', 'ctrl + E', edit, false, true, false),\r
3042                                                         CHANGE_BUTTON = MENU_BAR_CONTROL.EDIT.createSelection( 'change', 'ctrl + U', change, false, false, true),\r
3043                                                         jqStage,\r
3044                                                         jqConsoleParent,\r
3045                                                         jqConsoleWrapper,\r
3046                                                         jqConsoleTail,\r
3047                                                         jqImgConsole, jqTextConsole,\r
3048                                                         currentElement = null,\r
3049                                                         currentType = -1,\r
3050                                                         visible = false,\r
3051                                                         imgConsoleWidth, imgConsoleHeight,\r
3052                                                         textConsoleWidth, textConsoleHeight,\r
3053                                                         consoleWidth, consoleHeight,\r
3054                                                         consoleX, consoleY,\r
3055                                                         tailSize = 10,\r
3056                                                         buttonClickable = false;\r
3057                                                 \r
3058                                                 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 66, false, true, layerBack);\r
3059                                                 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 70, false, true, layerForward);\r
3060                                                 \r
3061                                                 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 68, false, true, del);\r
3062                                                 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 69, false, true, edit);\r
3063                                                 h2c.key.addKeyDownEvent( h2c.view.EDITOR, 85, false, true, change);\r
3064                                                 \r
3065                                                 function buttonBackOrForward( isBack){\r
3066                                                         var     offest = jqConsoleWrapper.offset();\r
3067                                                         jqConsoleWrapper.css( {\r
3068                                                                 position:       isBack === true ? '' : 'absolute',\r
3069                                                                 left:           isBack === true ? consoleX  : offest.left,\r
3070                                                                 top:            isBack === true ? consoleY  : offest.top\r
3071                                                         });\r
3072                                                         buttonClickable === isBack && ( isBack === true ? jqConsoleParent : jqStage).append( jqConsoleWrapper);\r
3073                                                         buttonClickable = !isBack;\r
3074                                                 }\r
3075                                                 function layerBack(){\r
3076                                                         if( currentElement === null) return;\r
3077                                                         replaceComicElement( currentElement, false);\r
3078                                                         updateInfomation();\r
3079                                                         SAVE( restoreReplaceObject, [ currentElement, true], [ currentElement, false]);\r
3080                                                         var _z = currentElement.z;\r
3081                                                         LAYER_BACK_BUTTON.visible( _z > 0);\r
3082                                                         LAYER_FORWARD_BUTTON.visible( _z < DRAGGABLE_ELEMENT_ARRAY.length -NUM_RESIZER -1);\r
3083                                                 }\r
3084                                                 function layerForward(){\r
3085                                                         if( currentElement === null) return;\r
3086                                                         replaceComicElement( currentElement, true);\r
3087                                                         updateInfomation();\r
3088                                                         SAVE( restoreReplaceObject, [ currentElement, false], [ currentElement, true]);\r
3089                                                         var _z = currentElement.z;\r
3090                                                         LAYER_BACK_BUTTON.visible( _z > 0);\r
3091                                                         LAYER_FORWARD_BUTTON.visible( _z < DRAGGABLE_ELEMENT_ARRAY.length -NUM_RESIZER -1);\r
3092                                                 }\r
3093                                                 function del(){\r
3094                                                         if( currentElement === null) return;\r
3095                                                         buttonBackOrForward( true);\r
3096                                                         removeComicElement( currentElement);\r
3097                                                         SAVE( restoreComicElement, [ true, currentElement], [ false, currentElement], true);\r
3098                                                         COMIC_ELEMENT_OPERATOR.hide();\r
3099                                                 }\r
3100                                                 function edit(){\r
3101                                                         if( currentElement === null) return;\r
3102                                                         TEXT_EDITOR_CONTROL.show( currentElement);\r
3103                                                         buttonBackOrForward( true);\r
3104                                                 }\r
3105                                                 function change(){\r
3106                                                         if( currentElement === null) return;\r
3107                                                         buttonBackOrForward( true);\r
3108                                                         IMAGE_GROUP_EXPROLER.show( currentElement.url);\r
3109                                                 }\r
3110                                                 return {\r
3111                                                         init: function(){\r
3112                                                                 jqStage = jqEditor;\r
3113                                                                 jqConsoleTail = $( '#comic-element-consol-tail');\r
3114                                                                 jqImgConsole = $( '#image-element-consol').hide();\r
3115                                                                 var imgConsoleSize = h2c.util.getElementSize( jqImgConsole.get( 0));\r
3116                                                                 imgConsoleWidth = imgConsoleSize.width;\r
3117                                                                 imgConsoleHeight = imgConsoleSize.height;\r
3118                                                                 \r
3119                                                                 jqTextConsole = $( '#text-element-consol').hide();\r
3120                                                                 var textConsoleSize = h2c.util.getElementSize( jqTextConsole.get( 0));\r
3121                                                                 textConsoleWidth = textConsoleSize.width;\r
3122                                                                 textConsoleHeight = textConsoleSize.height;\r
3123                                                                 \r
3124                                                                 jqConsoleWrapper = $( '#comic-element-consol-wrapper').hide();\r
3125                                                                 jqConsoleParent = jqConsoleWrapper.parent();\r
3126                                                                 \r
3127                                                                 $( '#edit-text-button').click( edit);\r
3128                                                                 $( '#delete-image-button, #delete-text-button').click( del);\r
3129                                                                 $( '#change-image-button').click( change);\r
3130                                                                 $( '#layer-forward-button, #forward-text-button').click( layerForward);\r
3131                                                                 $( '#layer-back-button, #back-text-button').click( layerBack);\r
3132                                                                                                                         \r
3133                                                                 delete COMIC_ELEMENT_CONSOLE.init;\r
3134                                                         },\r
3135                                                         show: function( _currentElement, _w, _h){\r
3136                                                                 visible === false && jqConsoleWrapper.show();\r
3137                                                                 visible = true;\r
3138                                                                 currentElement = _currentElement;\r
3139                                                                 var _currentType = _currentElement.type,\r
3140                                                                         _z = _currentElement.z;\r
3141                                                                 if( currentType !== _currentType){\r
3142                                                                         currentType = _currentType;\r
3143                                                                         jqImgConsole.toggle( _currentType === COMIC_ELEMENT_TYPE_IMAGE);\r
3144                                                                         jqTextConsole.toggle( _currentType === COMIC_ELEMENT_TYPE_TEXT);\r
3145                                                                         consoleWidth = _currentType === COMIC_ELEMENT_TYPE_IMAGE ? imgConsoleWidth : textConsoleWidth;\r
3146                                                                         consoleHeight = _currentType === COMIC_ELEMENT_TYPE_IMAGE ? imgConsoleHeight : textConsoleHeight;\r
3147                                                                 }\r
3148                                                                 consoleX = Math.floor( ( _w -consoleWidth) /2);\r
3149                                                                 \r
3150                                                                 LAYER_BACK_BUTTON.visible( _z > 0);\r
3151                                                                 LAYER_FORWARD_BUTTON.visible( _z < DRAGGABLE_ELEMENT_ARRAY.length -NUM_RESIZER -1);\r
3152                                                                 DELETE_BUTTON.visible( true);\r
3153                                                                 EDIT_BUTTON.visible( _currentType === COMIC_ELEMENT_TYPE_TEXT);\r
3154                                                                 CHANGE_BUTTON.visible( false);\r
3155                                                                 \r
3156                                                                 if( _w > consoleWidth * 1.5 && _h > consoleHeight * 1.5){\r
3157                                                                         consoleY = Math.floor( ( _h -consoleHeight) /2);\r
3158                                                                         jqConsoleWrapper.css( {\r
3159                                                                                 left:                   consoleX,\r
3160                                                                                 top:                    consoleY\r
3161                                                                         }).removeClass( 'console-out');\r
3162                                                                 } else {\r
3163                                                                         consoleY = _h +tailSize;\r
3164                                                                         jqConsoleWrapper.css( {\r
3165                                                                                 left:                   consoleX,\r
3166                                                                                 top:                    consoleY\r
3167                                                                         }).addClass( 'console-out');\r
3168                                                                 }\r
3169                                                         },\r
3170                                                         hide: function (){\r
3171                                                                 visible === true && jqConsoleWrapper.hide();\r
3172                                                                 visible = false;\r
3173                                                                 currentElement = null;\r
3174                                                                 LAYER_BACK_BUTTON.visible( false);\r
3175                                                                 LAYER_FORWARD_BUTTON.visible( false);\r
3176                                                                 DELETE_BUTTON.visible( false);\r
3177                                                                 EDIT_BUTTON.visible( false);\r
3178                                                                 CHANGE_BUTTON.visible( false);\r
3179                                                         },\r
3180                                                         x: function(){ return consoleX;},\r
3181                                                         y: function(){ return consoleY;},\r
3182                                                         w: function(){ return consoleWidth;},\r
3183                                                         h: function(){ return consoleHeight;},\r
3184                                                         onMouseMove: function( _mouseX, _mouseY){\r
3185                                                                 if( consoleX > _mouseX || consoleY > _mouseY || consoleX +consoleWidth < _mouseX || consoleY +consoleHeight < _mouseY){\r
3186                                                                         buttonClickable === true && buttonBackOrForward( true);\r
3187                                                                         return false;\r
3188                                                                 }\r
3189                                                                 buttonClickable === false && buttonBackOrForward( false);\r
3190                                                                 return true;\r
3191                                                         },\r
3192                                                         onMouseOut: function( _mouseX, _mouseY){\r
3193                                                                 buttonClickable === true && buttonBackOrForward( true);\r
3194                                                         }\r
3195                                                 }\r
3196                                         })(),\r
3197                                         TAIL_CONTROLER = ( function(){\r
3198                                                 var     ELM_MOVER = document.getElementById( 'balloon-tail-mover'),\r
3199                                                         SIZE = h2c.util.getElementSize( ELM_MOVER).width,\r
3200                                                         SIN = Math.sin,\r
3201                                                         COS = Math.cos,\r
3202                                                         ATAN = Math.atan,\r
3203                                                         FLOOR = Math.floor,\r
3204                                                         DEG_TO_RAD = Math.PI / 180,\r
3205                                                         RAD_TO_DEG = 1 /DEG_TO_RAD,\r
3206                                                         currentText = null,\r
3207                                                         tailX, tailY,\r
3208                                                         balloonW, balloonH, balloonA, radA,\r
3209                                                         visible = false,\r
3210                                                         startA;\r
3211                                                 \r
3212                                                 function draw( _w, _h, _a){\r
3213                                                         balloonW = _w !== undefined ? _w : balloonW;\r
3214                                                         balloonH = _h !== undefined ? _h : balloonH;\r
3215                                                         balloonA = _a !== undefined ? _a : balloonA;\r
3216                                                         radA = balloonA *DEG_TO_RAD;\r
3217                                                         tailX = FLOOR( ( ( COS( radA) /2 +0.5) *( balloonW +SIZE)) -SIZE /2);\r
3218                                                         tailY = FLOOR( ( ( SIN( radA) /2 +0.5) *( balloonH +SIZE)) -SIZE /2);\r
3219                                                         ELM_MOVER.style.left = tailX +'px';\r
3220                                                         ELM_MOVER.style.top = tailY +'px';\r
3221                                                         log.html( [ balloonW, balloonH, balloonA].join());\r
3222                                                 }\r
3223                                                 function hitTest( _mouseX, _mouseY){\r
3224                                                         var _x = tailX -SIZE /2,\r
3225                                                                 _y = tailY -SIZE /2;\r
3226                                                                 ret = currentIsTextElement === true && _x <= _mouseX && _y <= _mouseY && _x +SIZE >= _mouseX && _y +SIZE >= _mouseY;\r
3227                                                         ret === true && MOUSE_CURSOR( 'move');\r
3228                                                         return ret;\r
3229                                                 }\r
3230                                                 return {\r
3231                                                         update: draw,\r
3232                                                         show: function( _currentText){\r
3233                                                                 /*\r
3234                                                                  * visibilityのほうがいい, display:none だと ie で描画が狂う\r
3235                                                                  */\r
3236                                                                 ELM_MOVER.style.visibility = '';\r
3237                                                                 draw( _currentText.w, _currentText.h, _currentText.angle());\r
3238                                                                 currentText = _currentText;\r
3239                                                         },\r
3240                                                         hitTest: hitTest,\r
3241                                                         hide: function(){\r
3242                                                                 ELM_MOVER.style.visibility = 'hidden';\r
3243                                                                 currentText = null;\r
3244                                                         },\r
3245                                                         onStart: function( _currentText, _mouseX, _mouseY){\r
3246                                                                 if( hitTest( _mouseX -x, _mouseY -y) === true){\r
3247                                                                         currentText = _currentText;\r
3248                                                                         startA = _currentText.angle();\r
3249                                                                         return true;\r
3250                                                                 }\r
3251                                                                 currentText = null;\r
3252                                                                 return false;\r
3253                                                         },\r
3254                                                         onDrag: function( _mouseX, _mouseY){\r
3255                                                                 _mouseX = _mouseX -currentText.x -w /2;\r
3256                                                                 _mouseY = _mouseY -currentText.y -h /2; //Balloonの中心を0,0とする座標系に変換\r
3257                                                                 \r
3258                                                                 draw( w, h,\r
3259                                                                         _mouseX !== 0 ?\r
3260                                                                                 ATAN( _mouseY /_mouseX) *RAD_TO_DEG +( _mouseX < 0 ? 180 : 0) :\r
3261                                                                                 _mouseY > 0 ? 90 : -90\r
3262                                                                 );\r
3263                                                                 currentText && currentText.angle( balloonA);\r
3264                                                                 updateInfomation( undefined, undefined, undefined, balloonA);\r
3265                                                         },\r
3266                                                         onFinish: function(){\r
3267                                                                 startA !== currentText.angle() && saveComicElementStatus( x, y, w, h, startA);\r
3268                                                                 currentText = null;\r
3269                                                         },\r
3270                                                         onCancel: function(){\r
3271                                                                 resize( undefined, undefined, undefined, undefined, startA);\r
3272                                                         }\r
3273                                                 }\r
3274                                         })(),\r
3275                                         RESIZE_CONTROLER = ( function(){\r
3276                                                 var POSITION_ARRAY = [],\r
3277                                                         FLOOR = Math.floor,\r
3278                                                         CURSOR_AND_FLIP = [\r
3279                                                                 { cursor:       'n-resize',             v: 3},\r
3280                                                                 { cursor:       'e-resize',             h: 2},\r
3281                                                                 { cursor:       'e-resize',             h: 1},\r
3282                                                                 { cursor:       'n-resize',             v: 0},\r
3283                                                                 { cursor:       'nw-resize',    h: 5, v: 6, vh: 7},\r
3284                                                                 { cursor:       'ne-resize',    h: 4, v: 7, vh: 6},\r
3285                                                                 { cursor:       'ne-resize',    h: 7, v: 4, vh: 5},\r
3286                                                                 { cursor:       'nw-resize',    h: 6, v: 5, vh: 4}\r
3287                                                         ],      \r
3288                                                         elmResizerContainerStyle = document.getElementById( 'comic-element-resizer-container').style,\r
3289                                                         elmResizerTopStyle = document.getElementById( 'comic-element-resizer-top').style,\r
3290                                                         elmResizerLeftStyle = document.getElementById( 'comic-element-resizer-left').style,\r
3291                                                         elmResizerRightStyle = document.getElementById( 'comic-element-resizer-right').style,\r
3292                                                         elmResizerBottomStyle = document.getElementById( 'comic-element-resizer-bottom').style,\r
3293                                                         x, y, w, h,\r
3294                                                         currentIndex = -1,\r
3295                                                         currentElement,\r
3296                                                         currentIsTextElement = false;\r
3297                                                 \r
3298                                                 elmResizerContainerStyle.display = 'none';\r
3299                                                 \r
3300                                                 var RESIZE_WORK_ARRAY = [\r
3301                                                                 { x:    0, w:    0, y:  1, h:   -1}, //top\r
3302                                                                 { x:    1, w:   -1, y:  0, h:    0}, //left\r
3303                                                                 { x:    0, w:    1, y:  0, h:    0}, //right\r
3304                                                                 { x:    0, w:    0, y:  0, h:    1}, //bottom\r
3305                                                                 { x:    1, w:   -1, y:  1, h:   -1}, //top-left\r
3306                                                                 { x:    0, w:    1, y:  1, h:   -1}, //top-right\r
3307                                                                 { x:    1, w:   -1, y:  0, h:    1}, //bottom-left\r
3308                                                                 { x:    0, w:    1, y:  0, h:    1}  //bottom-right\r
3309                                                         ],\r
3310                                                         startX, startY, startW, startH, startFilpV, startFilpH, startAspect,\r
3311                                                         baseX, baseY, baseW, baseH,\r
3312                                                         currentX, currentY, currentW, currentH,\r
3313                                                         transX, transY, transW, transH,\r
3314                                                         xOffset, yOffset,\r
3315                                                         error = 0;\r
3316                                                 \r
3317                                                 function draw( _x, _y, _w, _h){\r
3318                                                         x = _x !== undefined ? _x : x;\r
3319                                                         y = _y !== undefined ? _y : y;\r
3320                                                         w = _w !== undefined ? _w : w;\r
3321                                                         h = _h !== undefined ? _h : h;\r
3322                                                         elmResizerContainerStyle.left = x +'px';\r
3323                                                         elmResizerContainerStyle.top = y +'px';\r
3324                                                         elmResizerContainerStyle.width = w +'px';\r
3325                                                         elmResizerContainerStyle.height = h +'px';\r
3326                                                         elmResizerTopStyle.left = FLOOR( w /2 -10 /2) +'px';\r
3327                                                         elmResizerLeftStyle.top = FLOOR( h /2 -10 /2) +'px';\r
3328                                                         elmResizerRightStyle.top = FLOOR( h /2 -10 /2) +'px';\r
3329                                                         elmResizerBottomStyle.left = FLOOR( w /2 -10 /2) +'px';\r
3330                                                         \r
3331                                                         POSITION_ARRAY.splice( 0, POSITION_ARRAY.length);\r
3332                                                         POSITION_ARRAY.push(\r
3333                                                                 {x:     x +5,                                   y:      y -HIT_AREA,            w:      w -5 *2,                h:      HIT_AREA +5},\r
3334                                                                 {x: x -HIT_AREA,                        y:      y +HIT_AREA +5,         w:      HIT_AREA +5,    h:      h -5 *2},\r
3335                                                                 {x: x +w -5,                            y:      y +HIT_AREA +5,         w:      HIT_AREA +5,    h:      h -5 *2},\r
3336                                                                 {x:     x +5,                                   y:      y +h -5,                        w:      w -5 *2,                h:      HIT_AREA +5},\r
3337                                                                 {x:     x -HIT_AREA,                    y:      y -HIT_AREA,            w:      HIT_AREA +5,    h:      HIT_AREA +5},\r
3338                                                                 {x: x +w -HIT_AREA,                     y:      y -HIT_AREA,            w:      HIT_AREA +5,    h:      HIT_AREA +5},\r
3339                                                                 {x:     x -HIT_AREA,                    y:      y +h -5,                        w:      HIT_AREA +5,    h:      HIT_AREA +5},\r
3340                                                                 {x:     x +w -5,                                y:      y +h -5,                        w:      HIT_AREA +5,    h:      HIT_AREA +5}\r
3341                                                         );\r
3342                                                 }\r
3343                                                 \r
3344                                                 function update( _x, _y, _w, _h){\r
3345                                                         transX = _x !== undefined ? _x : currentX;\r
3346                                                         transY = _y !== undefined ? _y : currentY;\r
3347                                                         transW = _w !== undefined ? _w : currentW;\r
3348                                                         transH = _h !== undefined ? _h : currentH;\r
3349                                                         \r
3350                                                         if( currentIsTextElement === false && currentIndex > 3 && h2c.key.shiftEnabled() === true){\r
3351                                                                 if( startAspect >= 1){\r
3352                                                                         _w = transW;\r
3353                                                                         transW = Math.floor( startAspect * transH);\r
3354                                                                         transX = transX +( currentIndex % 2 === 0 ? _w -transW : 0);\r
3355                                                                 } else {\r
3356                                                                         _h = transH;\r
3357                                                                         transH = Math.floor( transW / startAspect);\r
3358                                                                         transY = transY + ( currentIndex <= 5 ? _h -transH : 0);\r
3359                                                                 }\r
3360                                                         }\r
3361                                                         draw( transX, transY, transW, transH);\r
3362                                                         currentElement.resize( transX, transY, transW, transH);\r
3363                                                         currentIsTextElement === true && TAIL_CONTROLER.update( transW, transH);\r
3364                                                         COMIC_ELEMENT_CONSOLE.show( currentElement, transW, transH);\r
3365                                                         updateInfomation( transX, transY, undefined, undefined, transW, transH);\r
3366                                                 }\r
3367                                                 function getIndex( _mouseX, _mouseY){\r
3368                                                         var     p,\r
3369                                                                 l = POSITION_ARRAY.length;\r
3370                                                         for( var i=0; i<l; i++){\r
3371                                                                 p = POSITION_ARRAY[ i];\r
3372                                                                 if( p.x <= _mouseX && p.y <= _mouseY && p.x + p.w >= _mouseX && p.y +p.h >= _mouseY){\r
3373                                                                         MOUSE_CURSOR( CURSOR_AND_FLIP[ i].cursor);\r
3374                                                                         return currentIndex = i;\r
3375                                                                 }\r
3376                                                         }\r
3377                                                         return -1;\r
3378                                                 }\r
3379                                                 function flip( _flipV, _flipH){\r
3380                                                         var p = CURSOR_AND_FLIP[ currentIndex];\r
3381                                                         currentIndex = _flipH === true || _flipV === true ? p[\r
3382                                                                 _flipH === true && _flipV === true ? 'vh' : ( _flipH === true ? 'h' : 'v')\r
3383                                                         ] : currentIndex;\r
3384                                                         MOUSE_CURSOR( CURSOR_AND_FLIP[ currentIndex].cursor);\r
3385                                                         currentElement.flip( _flipV, _flipH);\r
3386                                                 }\r
3387                                                 return {\r
3388                                                         x: function(){ return x;},\r
3389                                                         y: function(){ return y;},\r
3390                                                         w: function(){ return w;},\r
3391                                                         h: function(){ return h;},\r
3392                                                         update: draw,\r
3393                                                         index: getIndex,\r
3394                                                         show: function( _currentElement){\r
3395                                                                 currentElement = _currentElement;\r
3396                                                                 currentIsTextElement = _currentElement.type === COMIC_ELEMENT_TYPE_TEXT;\r
3397                                                                 elmResizerContainerStyle.display = '';\r
3398                                                         },\r
3399                                                         hide: function(){\r
3400                                                                 currentElement = null;\r
3401                                                                 elmResizerContainerStyle.display = 'none';\r
3402                                                         },\r
3403                                                         onStart: function( _currentElement, _mouseX, _mouseY){\r
3404                                                                 currentElement = _currentElement;\r
3405                                                                 currentIsTextElement = _currentElement.type === COMIC_ELEMENT_TYPE_TEXT;\r
3406                                                                 if( _currentElement.keepSize === true) return false;\r
3407                                                                 currentIndex = getIndex( _mouseX, _mouseY);\r
3408                                                                 if( currentIndex === -1) return false;\r
3409                                                                 xOffset = _mouseX;\r
3410                                                                 yOffset = _mouseY;\r
3411                                                                 startX = baseX = _currentElement.x;\r
3412                                                                 startY = baseY = _currentElement.y;\r
3413                                                                 startW = baseW = _currentElement.w;\r
3414                                                                 startH = baseH = _currentElement.h;\r
3415                                                                 startFilpV = flipV;\r
3416                                                                 startFilpH = flipH;\r
3417                                                                 startAspect = startW /startH;\r
3418                                                                 return true;\r
3419                                                         },\r
3420                                                         onDrag: function( _mouseX, _mouseY){\r
3421                                                                 var com = RESIZE_WORK_ARRAY[ currentIndex],\r
3422                                                                         moveX = _mouseX -xOffset,\r
3423                                                                         moveY = _mouseY -yOffset,\r
3424                                                                         _x = baseX +moveX *com.x,\r
3425                                                                         _y = baseY +moveY *com.y,\r
3426                                                                         _w = baseW +moveX *com.w,\r
3427                                                                         _h = baseH +moveY *com.h,\r
3428                                                                         _updated = moveX !== 0 || moveY !== 0;\r
3429                                                                 \r
3430                                                                 // opera がときどき baseH の値を忘れる ??\r
3431                                                                 if( _x === undefined || _y === undefined || _w === undefined || _h === undefined){\r
3432                                                                         ++error;\r
3433                                                                         return;\r
3434                                                                 }\r
3435                                                                 \r
3436                                                                 if( _w >= MIN_OBJECT_SIZE && _h >= MIN_OBJECT_SIZE){\r
3437                                                                         \r
3438                                                                 } else \r
3439                                                                 if( _w >= -MIN_OBJECT_SIZE && _h >= -MIN_OBJECT_SIZE){\r
3440                                                                         return;\r
3441                                                                 } else \r
3442                                                                 if( currentElement.type === COMIC_ELEMENT_TYPE_TEXT){\r
3443                                                                         return;\r
3444                                                                 } else \r
3445                                                                 if( _w < -MIN_OBJECT_SIZE || _h < -MIN_OBJECT_SIZE){\r
3446                                                                         var __x = 0,\r
3447                                                                                 __y = 0;\r
3448                                                                         if( _w < -MIN_OBJECT_SIZE && _h > MIN_OBJECT_SIZE){\r
3449                                                                         // flipH\r
3450                                                                                 __x = _x;\r
3451                                                                                 baseX = _x = _x +_w;\r
3452                                                                                 baseY = _y;\r
3453                                                                                 baseW = _w = __x -_x;\r
3454                                                                                 baseH = _h;\r
3455                                                                                 flip( false, true);\r
3456                                                                                 flipV = currentElement.flipV();\r
3457                                                                         } else \r
3458                                                                         if( _w > MIN_OBJECT_SIZE && _h < -MIN_OBJECT_SIZE){\r
3459                                                                         // flipV\r
3460                                                                                 __y = _y;\r
3461                                                                                 baseX = _x;\r
3462                                                                                 baseY = _y = _y +_h;\r
3463                                                                                 baseW = _w;\r
3464                                                                                 baseH = _h = __y -_y;\r
3465                                                                                 flip( true, false);\r
3466                                                                                 flipH = currentElement.flipH();\r
3467                                                                         } else {\r
3468                                                                         // flipVH\r
3469                                                                                 __x = _x;\r
3470                                                                                 __y = _y;\r
3471                                                                                 baseX = _x = _x +_w;\r
3472                                                                                 baseY = _y = _y +_h;\r
3473                                                                                 baseW = _w = __x -_x;\r
3474                                                                                 baseH = _h = __y -_y;\r
3475                                                                                 flip( true, true);\r
3476                                                                                 flipV = currentElement.flipV();\r
3477                                                                                 flipH = currentElement.flipH();\r
3478                                                                         }\r
3479                                                                         _updated = true;\r
3480                                                                         xOffset = _mouseX;\r
3481                                                                         yOffset = _mouseY;      \r
3482                                                                 }\r
3483                                                                 currentX = _x;\r
3484                                                                 currentY = _y;\r
3485                                                                 currentW = _w;\r
3486                                                                 currentH = _h;\r
3487                                                                 _updated === true && update( _x, _y, _w, _h);\r
3488                                                                 \r
3489                                                                 log.html( [\r
3490                                                                                 'currentIndex:', currentIndex, \r
3491                                                                                 'baseW', baseW, 'baseH', baseH,'<br>',\r
3492                                                                                 'mouse', _mouseX, _mouseY,'<br>',\r
3493                                                                                 'move', moveX, moveY,'<br>',\r
3494                                                                                 'xy', _x, _y, 'wh',_w, _h,'<br>',\r
3495                                                                                 'com.w', com.w, 'com.h', com.h,'<br>',\r
3496                                                                                 'current',currentW, currentH,'<br>',\r
3497                                                                                 'trans', transY, transH,\r
3498                                                                                 'err', error\r
3499                                                                 ].join( ' , '));\r
3500                                                         },\r
3501                                                         onFinish: function(){\r
3502                                                                 MOUSE_CURSOR( '');\r
3503                                                                 if( currentW === w && currentH === h && currentX === x && currentY === y) return;\r
3504                                                                 resize( transX, transY, transW, transH);\r
3505                                                                 currentElement.resize( transX, transY, transW, transH);\r
3506                                                                 saveComicElementStatus( startX, startY, startW, startH, angle, startFilpV, startFilpH);\r
3507                                                         },\r
3508                                                         onCancel: function(){\r
3509                                                                 MOUSE_CURSOR( '');\r
3510                                                                 resize( startX, startY, startW, startH);\r
3511                                                                 currentElement.type === COMIC_ELEMENT_TYPE_IMAGE ?\r
3512                                                                         currentElement.animate( startX, startY, startW, startH, startFilpV, startFilpH) :\r
3513                                                                         currentElement.animate( startX, startY, startW, startH, angle);\r
3514                                                         },\r
3515                                                         onShiftUpdate: update,\r
3516                                                         onCtrlUpdate: update\r
3517                                                 }\r
3518                                         })(),\r
3519                                         POSITION_CONTROLER = ( function(){\r
3520                                                 var currentElement,\r
3521                                                         startX, startY,\r
3522                                                         currentX, currentY,\r
3523                                                         xOffset, yOffset,\r
3524                                                         isCopy = false;\r
3525                                                 \r
3526                                                 function update( _x, _y){\r
3527                                                         _x = currentX = _x !== undefined ? _x : currentX;\r
3528                                                         _y = currentY = _y !== undefined ? _y : currentY;\r
3529                                                         RESIZE_CONTROLER.update( _x, _y);\r
3530                                                         currentElement.resize( _x, _y);\r
3531                                                         updateInfomation( _x, _y);                                                      \r
3532                                                 }\r
3533                                                 \r
3534                                                 return {\r
3535                                                         onStart: function( _currentElement, _mouseX, _mouseY){\r
3536                                                                 currentElement = _currentElement;\r
3537                                                                 xOffset = _mouseX;\r
3538                                                                 yOffset = _mouseY;\r
3539                                                                 startX = currentX = x;\r
3540                                                                 startY = currentY = y;\r
3541                                                                 MOUSE_CURSOR( 'move');\r
3542                                                         },\r
3543                                                         onDrag: function( _mouseX, _mouseY){\r
3544                                                                 var moveX = _mouseX -xOffset,\r
3545                                                                         moveY = _mouseY -yOffset,\r
3546                                                                         _x = x +moveX,\r
3547                                                                         _y = y +moveY;\r
3548                                                                 if( GRID_ENABLED() === true){\r
3549                                                                         _x = Math.floor( _x / 10) * 10;\r
3550                                                                         _y = Math.floor( _y / 10) * 10;\r
3551                                                                 }\r
3552                                                                 update( _x, _y);\r
3553                                                         },\r
3554                                                         onFinish: function(){\r
3555                                                                 MOUSE_CURSOR( '');\r
3556                                                                 if( currentX === startX && currentY === startY) return;\r
3557                                                                 resize( currentX, currentY);\r
3558                                                                 currentElement.resize( currentX, currentY);\r
3559                                                                 saveComicElementStatus( startX, startY);\r
3560                                                         },\r
3561                                                         onCancel: function(){\r
3562                                                                 MOUSE_CURSOR( '');\r
3563                                                                 resize( startX, startY);\r
3564                                                                 currentElement.animate( startX, startY);\r
3565                                                         },\r
3566                                                         onShiftUpdate: update,\r
3567                                                         onCtrlUpdate: update\r
3568                                                 }\r
3569                                         })();\r
3570 \r
3571                                         function resize( _x, _y, _w, _h, _angle){\r
3572                                                 x = _x !== undefined ? _x : x;\r
3573                                                 y = _y !== undefined ? _y : y;\r
3574                                                 w = _w !== undefined ? _w : w;\r
3575                                                 h = _h !== undefined ? _h : h;\r
3576                                                 angle = _angle !== undefined ? _angle : angle;\r
3577 \r
3578                                                 RESIZE_CONTROLER.update( x, y, w, h);\r
3579                                                 currentIsTextElement === true && TAIL_CONTROLER.update( w, h, angle);\r
3580                                                 COMIC_ELEMENT_CONSOLE.show( currentElement, w, h);\r
3581                                                 updateInfomation( x, y, currentElement.z, angle, w, h);\r
3582                                         }\r
3583                                         function updateInfomation( _x, _y, _z, _a, _w, _h, keepAspect){\r
3584                                                 _w = _w !== undefined ? _w : w;\r
3585                                                 _h = _h !== undefined ? _h : h;\r
3586                                                 INFOMATION(\r
3587                                                         currentElement === null ? -1 : currentElement.type,\r
3588                                                         _x !== undefined ? _x : x,\r
3589                                                         _y !== undefined ? _y : y,\r
3590                                                         _z !== undefined ? _z : ( currentElement === null ? '*' : currentElement.z),\r
3591                                                         _a !== undefined ? Math.floor( _a) : ( currentIsTextElement === true ? Math.floor( angle) : '-'),\r
3592                                                         _w,\r
3593                                                         _h,\r
3594                                                         currentElement === null || currentIsTextElement === true ? '-' : ( currentElement.actualW() === 0 ? '?' : Math.floor( _w / currentElement.actualW() *100)),\r
3595                                                         currentElement === null || currentIsTextElement === true ? '-' : ( currentElement.actualH() === 0 ? '?' : Math.floor( _h / currentElement.actualH() *100)),\r
3596                                                         currentElement === null || currentIsTextElement === true ? '-' : currentElement.keepAspect\r
3597                                                 );\r
3598                                         }\r
3599                                         function show( _currentElement){\r
3600                                                 currentElement === null && RESIZE_CONTROLER.show( _currentElement);\r
3601                                                 if( currentElement !== _currentElement){\r
3602                                                         currentElement = _currentElement;\r
3603                                                         \r
3604                                                         currentIsTextElement = ( _currentElement.type === COMIC_ELEMENT_TYPE_TEXT);\r
3605                                                         currentIsTextElement === true ? TAIL_CONTROLER.show( _currentElement) : TAIL_CONTROLER.hide();\r
3606                                                         \r
3607                                                         flipV = currentIsTextElement === false ? _currentElement.flipV() : 0;\r
3608                                                         flipH = currentIsTextElement === false ? _currentElement.flipH() : 0;\r
3609                                                         \r
3610                                                         resize(\r
3611                                                                 _currentElement.x, _currentElement.y, _currentElement.w, _currentElement.h,\r
3612                                                                 currentIsTextElement === true ? _currentElement.angle() : 0\r
3613                                                         );\r
3614                                                 }\r
3615                                         }\r
3616                                         function hide(){\r
3617                                                 currentElement !== null && RESIZE_CONTROLER.hide();\r
3618                                                 currentElement = null;\r
3619                                                 MOUSE_CURSOR( '');\r
3620                                                 TAIL_CONTROLER.hide();\r
3621                                                 COMIC_ELEMENT_CONSOLE.hide();\r
3622                                                 updateInfomation();\r
3623                                         }\r
3624                                         function restoreState( arg){\r
3625                                                 if( arg && arg.length !== 8) return;\r
3626                                                 var _currentElement = arg[ 0],\r
3627                                                         _x = arg[ 1], _y = arg[ 2], _w = arg[ 3], _h = arg[ 4],\r
3628                                                         _a = arg[ 5],\r
3629                                                         _flipV = arg[ 6], _flipH = arg[ 7];\r
3630                                                 if( !_currentElement) return;\r
3631                                                 _currentElement.type === COMIC_ELEMENT_TYPE_IMAGE ?\r
3632                                                         _currentElement.animate( _x, _y, _w, _h, _flipV, _flipH) :\r
3633                                                         _currentElement.animate( _x, _y, _w, _h, _a);\r
3634                                                 currentControler = null;\r
3635                                                 currentElement === _currentElement ? resize( _x, _y, _w, _h, _a) : show( _currentElement);\r
3636                                         }\r
3637                                         function saveComicElementStatus( startX, startY, startW, startH, startA, startFilpV, startFilpH){\r
3638                                                 startX = startX !== undefined ? startX : x;\r
3639                                                 startY = startY !== undefined ? startY : y;\r
3640                                                 startW = startW !== undefined ? startW : w;\r
3641                                                 startH = startH !== undefined ? startH : h;\r
3642                                                 startA = startA !== undefined ? startA : angle;\r
3643                                                 startFilpV = startFilpV !== undefined ? startFilpV : flipV;\r
3644                                                 startFilpH = startFilpH !== undefined ? startFilpH : flipH;\r
3645                                                 currentElement && SAVE( restoreState,\r
3646                                                         [ currentElement, startX, startY, startW, startH, startA, startFilpV, startFilpH],\r
3647                                                         [ currentElement, x, y, w, h, angle, flipV, flipH]\r
3648                                                 );\r
3649                                         }\r
3650                                         h2c.key.addKeyUpdateEvent( h2c.view.EDITOR, 16, true, undefined, function( e){\r
3651                                                 currentControler !== null && currentControler.onShiftUpdate && currentControler.onShiftUpdate();\r
3652                                         });\r
3653                                         h2c.key.addKeyUpdateEvent( h2c.view.EDITOR, 17, undefined, true, function(){\r
3654                                                 currentControler !== null && currentControler.onCtrlUpdate && currentControler.onCtrlUpdate();\r
3655                                         });\r
3656                                         h2c.key.addKeyDownEvent( h2c.view.EDITOR, 27, false, false, function(){\r
3657                                                 currentControler !== null && currentControler.onCancel && currentControler.onCancel();\r
3658                                                 currentControler = null;\r
3659                                         });\r
3660                                 return {\r
3661                                         init: function(){\r
3662                                                 COMIC_ELEMENT_CONSOLE.init();\r
3663                                                 hide();\r
3664                                                 delete COMIC_ELEMENT_OPERATOR.init;\r
3665                                         },\r
3666                                         hide: hide,\r
3667                                         busy: function(){\r
3668                                                 return currentControler !== null;\r
3669                                         },\r
3670                                         hitareaX: function( _comicElement, _x){\r
3671                                                 if( _comicElement === currentElement){\r
3672                                                         var _consoleX = COMIC_ELEMENT_CONSOLE.x();\r
3673                                                         return x +( _consoleX < 0 ? _consoleX : 0) -HIT_AREA;\r
3674                                                 }\r
3675                                                 return _x -HIT_AREA;\r
3676                                         },\r
3677                                         hitareaY: function( _comicElement, _y){\r
3678                                                 return _y -HIT_AREA;\r
3679                                         },\r
3680                                         hitareaW: function( _comicElement, _w){\r
3681                                                 if( _comicElement === currentElement){\r
3682                                                         var _consoleW = COMIC_ELEMENT_CONSOLE.w();\r
3683                                                         return ( _consoleW < w ? w : _consoleW) +HIT_AREA *2;\r
3684                                                 }\r
3685                                                 return _w +HIT_AREA *2;\r
3686                                         },\r
3687                                         hitareaH: function( _comicElement, _h){\r
3688                                                 if( _comicElement === currentElement){\r
3689                                                         var _consoleY = COMIC_ELEMENT_CONSOLE.y();\r
3690                                                         return ( _consoleY < h ? h : _consoleY +COMIC_ELEMENT_CONSOLE.h()) +HIT_AREA *2;\r
3691                                                 }\r
3692                                                 return _h +HIT_AREA *2;\r
3693                                         },\r
3694                                         onMouseDown: function( _currentElement, _mouseX, _mouseY){\r
3695                                                 //show( _currentElement);\r
3696                                                 if( currentIsTextElement === true && TAIL_CONTROLER.onStart( _currentElement, _mouseX, _mouseY) === true){\r
3697                                                         currentControler = TAIL_CONTROLER;\r
3698                                                 } else\r
3699                                                 if( RESIZE_CONTROLER.onStart( _currentElement, _mouseX, _mouseY) === true){\r
3700                                                         currentControler = RESIZE_CONTROLER;\r
3701                                                 } else {\r
3702                                                         POSITION_CONTROLER.onStart( _currentElement, _mouseX, _mouseY)\r
3703                                                         currentControler = POSITION_CONTROLER;\r
3704                                                 }\r
3705                                         },\r
3706                                         onMouseMove: function( _currentElement, _mouseX, _mouseY){\r
3707                                                 show( _currentElement);\r
3708                                                 if( currentControler !== null){\r
3709                                                         currentControler.onDrag( _mouseX, _mouseY);                                             \r
3710                                                 } else {\r
3711                                                         currentElement && COMIC_ELEMENT_CONSOLE.onMouseMove( _mouseX -x, _mouseY -y);\r
3712                                                         TAIL_CONTROLER.hitTest( _mouseX -x, _mouseY -y) === false && RESIZE_CONTROLER.index( _mouseX, _mouseY) === -1 && MOUSE_CURSOR( '');\r
3713                                                 }\r
3714                                         },\r
3715                                         onMouseUp: function( _currentElement, _mouseX, _mouseY){\r
3716                                                 currentControler !== null && currentControler.onFinish();\r
3717                                                 currentControler = null;\r
3718                                         },\r
3719                                         onMouseClick: function( _mouseX, _mouseY){\r
3720                                                 //return currentElement ? COMIC_ELEMENT_CONSOLE.onMouseClick( _mouseX -x, _mouseY -y) : false;\r
3721                                         }\r
3722                                 }\r
3723                         })();\r
3724                         /*\r
3725                          *  // COMIC_ELEMENT_OPERATOR\r
3726                          */\r
3727                 \r
3728                         var AbstractComicElement = function( JQ_WAPPER, COMIC_ELM_TYPE, update, x, y, w, h, z, timing){\r
3729                                 var OPERATOR = COMIC_ELEMENT_OPERATOR;\r
3730                                 return {\r
3731                                         $: JQ_WAPPER,\r
3732                                         type: COMIC_ELM_TYPE,\r
3733                                         x: x,\r
3734                                         y: y,\r
3735                                         w: w,\r
3736                                         h: h,                                   \r
3737                                         z: z,\r
3738                                         timing: timing,\r
3739                                         hitareaX: function(){ return OPERATOR.hitareaX( this, this.x);},\r
3740                                         hitareaY: function(){ return OPERATOR.hitareaY( this, this.y);},\r
3741                                         hitareaW: function(){ return OPERATOR.hitareaW( this, this.w);},\r
3742                                         hitareaH: function(){ return OPERATOR.hitareaH( this, this.h);},\r
3743                                         shift: function( _shiftX, _shiftY){\r
3744                                                 update( this.x +_shiftX, this.y +_shiftY);\r
3745                                         },\r
3746                                         busy: function(){\r
3747                                                 return OPERATOR.busy();\r
3748                                         },\r
3749                                         onMouseMove: function( _mouseX, _mouseY){\r
3750                                                 OPERATOR.onMouseMove( this, _mouseX, _mouseY);\r
3751                                         },\r
3752                                         onMouseUp: function( _mouseX, _mouseY){\r
3753                                                 OPERATOR.onMouseUp( this, _mouseX, _mouseY);\r
3754                                         },\r
3755                                         onMouseDown: function( _mouseX, _mouseY){\r
3756                                                 OPERATOR.onMouseDown( this, _mouseX, _mouseY);\r
3757                                         }\r
3758                                 }\r
3759                         };\r
3760                 /*\r
3761                  * --------------------------------------------------------------------------------------------\r
3762                  * ImageElementClass\r
3763                  */\r
3764                         var     jqImageElementOrigin;\r
3765                         var ImageElementClass = function( url, IMAGE_SET_ID, x, y, z, w, h, timing){\r
3766                                 jqImageElementOrigin = jqImageElementOrigin || $( $( '#imgElementTemplete').remove().html());\r
3767                                 \r
3768                                 var JQ_WRAPPER = jqImageElementOrigin.clone( true),\r
3769                                         OPERATOR = COMIC_ELEMENT_OPERATOR,\r
3770                                         SAVE = HISTORY.saveState,\r
3771                                         HIT_AREA = MOUSE_HIT_AREA,\r
3772                                         reversibleImage = null,\r
3773                                         actualW = 0, actualH = 0,\r
3774                                         flipH = w < 0 ? -1 : 1,\r
3775                                         flipV = h < 0 ? -1 : 1,\r
3776                                         instance;\r
3777                                 w = Math.floor( w);\r
3778                                 h = Math.floor( h);\r
3779                                 \r
3780                                 function update( _x, _y, _w, _h, animate){\r
3781                                         instance.x = x = _x !== undefined ? _x : x;\r
3782                                         instance.y = y = _y !== undefined ? _y : y;\r
3783                                         instance.w = w = _w !== undefined ? _w : w;\r
3784                                         instance.h = h = _h !== undefined ? _h : h;\r
3785                                         JQ_WRAPPER[ animate === true ? 'animate' : 'css']( { \r
3786                                                 left:   x,\r
3787                                                 top:    y,\r
3788                                                 width:  w,\r
3789                                                 height: h\r
3790                                         }, 250, function(){ reversibleImage.resize( flipH * w, flipV * h);});\r
3791                                         animate !== true && reversibleImage.resize( flipH * w, flipV * h);\r
3792                                 }\r
3793                                 \r
3794                                 function updateUrl( _url){\r
3795                                         if( url === _url) return;\r
3796                                         url = _url || url;\r
3797                                         var _reversibleImage = h2c.image.createReversibleImage( url, flipH * w, flipV * h, function( _url, _actualW, _actualH){\r
3798                                                 actualW = _actualW;\r
3799                                                 actualH = _actualH;\r
3800                                         });\r
3801                                         if( reversibleImage !== null){\r
3802                                                 JQ_WRAPPER.children( reversibleImage.elm).replaceWith( _reversibleImage.elm);\r
3803                                                 reversibleImage.destroy();\r
3804                                         } else {\r
3805                                                 JQ_WRAPPER.append( _reversibleImage.elm);\r
3806                                         }\r
3807                                         reversibleImage = _reversibleImage;\r
3808                                 }\r
3809                                 return h2c.util.extend(\r
3810                                         AbstractComicElement.apply( this, [ JQ_WRAPPER, COMIC_ELEMENT_TYPE_IMAGE, update, x, y, w, h, z, timing]),\r
3811                                         {\r
3812                                                 init: function(){\r
3813                                                         instance = this;\r
3814                                                         updateUrl();\r
3815                                                         update();\r
3816                                                         delete this.init;\r
3817                                                 },\r
3818                                                 flip: function( _flipH, _flipV){\r
3819                                                         if( _flipH !== true && _flipV !== true) return;\r
3820                                                         flipH = _flipH === true ? -flipH : flipH;\r
3821                                                         flipV = _flipV === true ? -flipV : flipV;\r
3822                                                         reversibleImage.resize( flipH * w, flipV * h);\r
3823                                                 },\r
3824                                                 flipV: function(){\r
3825                                                         return flipV;\r
3826                                                 },\r
3827                                                 flipH: function(){\r
3828                                                         return flipH;\r
3829                                                 },\r
3830                                                 url: function( _url, _actualW, _actualH){\r
3831                                                         if( _url && _url !== url){\r
3832                                                                 SAVE( updateUrl, url, _url);\r
3833                                                                 actualW = _actualW;\r
3834                                                                 actualH = _actualH;\r
3835                                                                 updateUrl( _url);\r
3836                                                         }\r
3837                                                         return url;\r
3838                                                 },\r
3839                                                 actualW: function(){ return actualW;},\r
3840                                                 actualH: function(){ return actualH;},\r
3841                                                 keepSize: false,\r
3842                                                 resize: update,\r
3843                                                 animate: function ( _x, _y, _w, _h, _flipH, _flipV){\r
3844                                                         flipH = _flipH !== undefined ? _flipH : flipH;\r
3845                                                         flipV = _flipV !== undefined ? _flipV : flipV;\r
3846                                                         update( _x, _y, _w, _h, true);\r
3847                                                 },\r
3848                                                 getAsHTML: function( isAbsoluteUrl, isXHTML){\r
3849                                                         return [\r
3850                                                                 '<img ',\r
3851                                                                         'src="', isAbsoluteUrl !== true ? url : h2c.util.getAbsolutePath( url), '" ',\r
3852                                                                         'width="', w, '" ',\r
3853                                                                         'height="', h, '" ',\r
3854                                                                         'style="',                                                                      \r
3855                                                                                 'left:', x, 'px;',\r
3856                                                                                 'top:', y, 'px;',\r
3857                                                                                 'z-index:', z, ';',\r
3858                                                                         '"',\r
3859                                                                 isXHTML !== true ? '>' : ' \/>'\r
3860                                                         ].join( '');\r
3861                                                 },\r
3862                                                 getAsJsonString: function(){\r
3863                                                         var cr = h2c.LINE_FEED_CODE_TEXTAREA;\r
3864                                                         return [\r
3865                                                                 '"new', this.timing, '": {', cr,\r
3866                                                                         '"resource_picture_id": "', url, '",', cr,\r
3867                                                                         '"x": ', x, ',', cr,\r
3868                                                                         '"y": ', y, ',', cr,\r
3869                                                                         '"z": ', z, ',', cr,\r
3870                                                                         '"w": ', w, ',', cr,\r
3871                                                                         '"h": ', h, ',', cr,\r
3872                                                                         '"flipv": ', flipV === true ? 1 : 0, ',', cr,\r
3873                                                                         '"fliph": ', flipH === true ? 1 : 0, ',', cr,\r
3874                                                                         '"t": ', this.timing, cr,\r
3875                                                                 '}'\r
3876                                                         ].join( '');\r
3877                                                 },\r
3878                                                 destroy: function(){\r
3879                                                         reversibleImage.destroy();\r
3880                                                         JQ_WRAPPER.remove();\r
3881                                                         JQ_WRAPPER = reversibleImage = OPERATOR = null;\r
3882                                                         delete this.destroy;\r
3883                                                 }\r
3884                                         }\r
3885                                 );\r
3886                         }\r
3887                 /*\r
3888                  * / ImageElementClass\r
3889                  * --------------------------------------------------------------------------------------------\r
3890                  */\r
3891 \r
3892 \r
3893                 /*\r
3894                  * --------------------------------------------------------------------------------------------\r
3895                  * TextElementClass\r
3896                  * \r
3897                  * ELM はh2c.domで書き出したものを突っ込むcreateの場合\r
3898                  * \r
3899                  * type\r
3900                  * 0.none\r
3901                  * 1.speach balloon\r
3902                  * 2.think\r
3903                  * 3.bom\r
3904                  * 4.black-box( dq style)\r
3905                  * 5.blue-box( ff style)\r
3906                  * \r
3907                  */\r
3908                         var jqTextElementOrigin;\r
3909                         var TextElementClass = function( type, a, text, x, y, z, w, h, timing){\r
3910                                 jqTextElementOrigin = jqTextElementOrigin || ( function(){\r
3911                                         var _OLD_IE = $( $( '#textElementTempleteForOldIE').remove().html()),\r
3912                                                 _MODERN = $( $( '#textElementTemplete').remove().html());\r
3913                                         return h2c.isIE === true && h2c.ieRenderingVersion < 8 ? _OLD_IE : _MODERN;\r
3914                                 })();\r
3915                                 \r
3916                                 var JQ_WRAPPER = jqTextElementOrigin.clone( true),\r
3917                                         XBROWSER_BALLOON = h2c.balloon.createBalloon( w, h, a, type),\r
3918                                         TEXT_ELM = JQ_WRAPPER.find( 'td,.speach-inner').eq( 0),\r
3919                                         OPERATOR = COMIC_ELEMENT_OPERATOR,\r
3920                                         HIT_AREA = MOUSE_HIT_AREA,\r
3921                                         SAVE = HISTORY.saveState,\r
3922                                         instance;\r
3923                                         \r
3924                                 JQ_WRAPPER.find( 'img').eq( 0).replaceWith( XBROWSER_BALLOON.elm);\r
3925                                 \r
3926                                 function update( _x, _y, _w, _h, _a, animate){\r
3927                                         instance.x = x = _x !== undefined ? _x : x;\r
3928                                         instance.y = y = _y !== undefined ? _y : y;\r
3929                                         instance.w = w = _w !== undefined ? _w : w;\r
3930                                         instance.h = h = _h !== undefined ? _h : h;\r
3931                                         a = _a !== undefined ? _a : a;\r
3932                                         \r
3933                                         JQ_WRAPPER[ animate === true ? 'animate' : 'css']( {\r
3934                                                         left:           x,\r
3935                                                         top:            y,\r
3936                                                         width:          w,\r
3937                                                         height:         h\r
3938                                                 }, 250,\r
3939                                                 function(){\r
3940                                                         XBROWSER_BALLOON.resize( a, w, h);\r
3941                                                 }\r
3942                                         );              \r
3943                                         animate !== true && XBROWSER_BALLOON.resize( a, w, h);\r
3944                                 }\r
3945                                 \r
3946                                 function updateType( _type){\r
3947                                         if( type !== _type){\r
3948                                                 type = _type || type;\r
3949                                                 XBROWSER_BALLOON.type( type);\r
3950                                         }\r
3951                                 }\r
3952                                 function updateAngle( _a){\r
3953                                         if( _a !== undefined && a !== _a){\r
3954                                                 a = _a !== undefined ? _a : a;\r
3955                                                 XBROWSER_BALLOON.angle( a);\r
3956                                         }\r
3957                                 }\r
3958                                 function updateText( _text){\r
3959                                         text = _text || text || '';\r
3960                                         TEXT_ELM.html( text);\r
3961                                 }\r
3962                                 \r
3963                                 return h2c.util.extend(\r
3964                                         AbstractComicElement.apply( this, [ JQ_WRAPPER, COMIC_ELEMENT_TYPE_TEXT, update, x, y, w, h, z, timing]),\r
3965                                         {\r
3966                                                 init: function(){\r
3967                                                         instance = this;\r
3968                                                         updateText();\r
3969                                                         update();\r
3970                                                         delete this.init;\r
3971                                                 },\r
3972                                                 angle: function( _a){\r
3973                                                         _a !== undefined && update( undefined, undefined, undefined, undefined, _a);\r
3974                                                         return a;\r
3975                                                 },\r
3976                                                 text: function( _text){\r
3977                                                         if( _text && text !== _text) {\r
3978                                                                 SAVE( updateText, text || '', _text);\r
3979                                                                 updateText( _text);\r
3980                                                         }\r
3981                                                         return text;\r
3982                                                 },\r
3983                                                 resize: update,\r
3984                                                 animate: function ( _x, _y, _w, _h, _a){\r
3985                                                         update( _x, _y, _w, _h, _a, true);\r
3986                                                 },\r
3987                                                 destroy: function(){\r
3988                                                         JQ_WRAPPER.remove();\r
3989                                                         XBROWSER_BALLOON.destroy();\r
3990                                                         OPERATOR = null;\r
3991                                                         delete this.destroy;\r
3992                                                 },\r
3993                                                 getAsJSON: function(){\r
3994                                                         \r
3995                                                 },\r
3996                                                 getAsJsonString: function(){\r
3997                                                         var cr = h2c.LINE_FEED_CODE_TEXTAREA;\r
3998                                                         return [\r
3999                                                                 '"new', this.timing, '": {', cr,\r
4000                                                                         '"balloon_template_id": ', 1, ',', cr,\r
4001                                                                         '"resource_picture_id": ', 1, ',', cr,\r
4002                                                                         '"border": ', 1, ',', cr,\r
4003                                                                         '"tail": ', a, ',', cr,\r
4004                                                                         '"x": ', x, ',', cr,\r
4005                                                                         '"y": ', y, ',', cr,\r
4006                                                                         '"z": ', z, ',', cr,\r
4007                                                                         '"w": ', w, ',', cr,\r
4008                                                                         '"h": ', h, ',', cr,\r
4009                                                                         '"t": ', this.timing, ',', cr,\r
4010                                                                 '"speaches_attributes": {', cr,\r
4011                                                                         '"newf', this.timing, '": {', cr,\r
4012                                                                         '"content": "', text, '",', cr,\r
4013                                                                                         '"x": ', x, ',', cr,\r
4014                                                                                         '"y": ', y, ',', cr,\r
4015                                                                                         '"w": ', w, ',', cr,\r
4016                                                                                         '"h": ', h, cr,\r
4017                                                                                 '}', cr,\r
4018                                                                         '}', cr,\r
4019                                                                 '}'\r
4020                                                         ].join( '');\r
4021                                                 },\r
4022                                                 getAsHTML: function( isAbsoluteUrl, isXHTML){\r
4023                                                         var url = XBROWSER_BALLOON.getURL();\r
4024                                                         return [\r
4025                                                                 '<img ',\r
4026                                                                         'src="', isAbsoluteUrl !== true ? url : h2c.util.getAbsolutePath( url), '" ',\r
4027                                                                         'width="', w, '" ',\r
4028                                                                         'height="', h, '" ',\r
4029                                                                         'style="',                                                                      \r
4030                                                                                 'left:', x, 'px;',\r
4031                                                                                 'top:', y, 'px;',\r
4032                                                                                 'z-index:', z, ';',\r
4033                                                                         '"',\r
4034                                                                 isXHTML !== true ? '>' : ' \/>',\r
4035                                                                 h2c.LINE_FEED_CODE_TEXTAREA,\r
4036                                                                 '<div class="balloon" style="',\r
4037                                                                         'left:', x, 'px;',\r
4038                                                                         'top:', y, 'px;',\r
4039                                                                         'width:', w, 'px;',\r
4040                                                                         'height:', h, 'px;',\r
4041                                                                         'z-index:', z,\r
4042                                                                 '"><span>', text, '<\/span>', '<\/div>'\r
4043                                                                         \r
4044                                                         ].join( '');\r
4045                                                 },\r
4046                                                 getAsXML: function(){}\r
4047                                                 \r
4048                                         }\r
4049                                 );\r
4050                         }\r
4051                 /*\r
4052                  * リサイズが、ResizerTopによって行われた場合、comicElementのyを動かして見かけ上動かないようにする。\r
4053                  */     \r
4054                         function resize( isResizerTopAction){\r
4055                                 if( isResizerTopAction === true){\r
4056                                         var     _shiftX = canvasW -_canvasW,\r
4057                                                 _shiftY = canvasH -_canvasH,\r
4058                                                 l = DRAGGABLE_ELEMENT_ARRAY.length;\r
4059                                         for( var i = NUM_RESIZER; i < l; i++){\r
4060                                                 DRAGGABLE_ELEMENT_ARRAY[ i].shift( _shiftX, _shiftY);\r
4061                                         }\r
4062                                 }\r
4063                                 _canvasW = canvasW;\r
4064                                 _canvasH = canvasH;\r
4065                                 \r
4066                                 comicElementContainer.css( {\r
4067                                         width:  _canvasW,\r
4068                                         height: _canvasH,\r
4069                                         top:    canvasY,\r
4070                                         left:   canvasX\r
4071                                 });\r
4072                         }\r
4073                 \r
4074                 /*\r
4075                  * append, remove, replace\r
4076                  * \r
4077                  * comicElement には、z-position と dom-index がある。\r
4078                  *   z-position は 表示上の位置。大きいほど前に表示される( z-index)\r
4079                  *   dom-index は 意味上の順番。htmlタグの登場順で、検索結果や音声読み上げブラウザで正しく意味が取れる順番。\r
4080                  * \r
4081                  * editerでは、実際には z-index は使わず、htmlの順序で前後を表現する。\r
4082                  * dom-index は、数値のみ保持して、投稿時にcomicElementを適宜に並び替える。\r
4083                  * \r
4084                  * append comicElement\r
4085                  * 1. 新しい comicElement の z-position を得る\r
4086                  * 2. z の同じ comicElementを見つけ、その前に加える。または一番先頭へ。(DRAGGABLE_ELEMENT_ARRAY)\r
4087                  *    zが大きいほど、DRAGGABLE_ELEMENT_ARRAYの先頭へ。但しNUM_RESIZER番目より下。\r
4088                  * 3. dom位置は、DRAGGABLE_ELEMENT_ARRAY とは反対に、前のものほど後ろへ。\r
4089                  * \r
4090                  * \r
4091                  * remove comicElement\r
4092                  * 1. remove\r
4093                  * 2. renumber z\r
4094                  */\r
4095                         function appendComicElement( _comicElement) {\r
4096                                 _comicElement.init && _comicElement.init();\r
4097                                 var z = _comicElement.z,\r
4098                                         l = DRAGGABLE_ELEMENT_ARRAY.length;\r
4099                                 _comicElement.$.stop().css( {\r
4100                                         filter:         '',\r
4101                                         opacity:        ''\r
4102                                 });\r
4103                                 if( z === undefined || z === NaN || z < 0 || z >= l -NUM_RESIZER){\r
4104                                         DRAGGABLE_ELEMENT_ARRAY.splice( NUM_RESIZER, 0, _comicElement);\r
4105                                         comicElementContainer.append( _comicElement.$.fadeIn());\r
4106                                 } else {\r
4107                                         var insertIndex = ( function(){\r
4108                                                         for( var ret = NUM_RESIZER; ret < l; ++ret){\r
4109                                                                 if( DRAGGABLE_ELEMENT_ARRAY[ ret].z <= z) return ret +1;\r
4110                                                         }\r
4111                                                         return NUM_RESIZER;\r
4112                                                 })();\r
4113                                         DRAGGABLE_ELEMENT_ARRAY[ insertIndex -1].$.after( _comicElement.$.fadeIn());\r
4114                                         DRAGGABLE_ELEMENT_ARRAY.splice( insertIndex, 0, _comicElement);\r
4115                                 }\r
4116                                 sortComicElement();\r
4117                         }\r
4118                         function removeComicElement( _comicElement) {\r
4119                                 var l = DRAGGABLE_ELEMENT_ARRAY.length;\r
4120                                 for( var i=NUM_RESIZER; i<l; ++i){\r
4121                                         if( DRAGGABLE_ELEMENT_ARRAY[ i] === _comicElement){\r
4122                                                 DRAGGABLE_ELEMENT_ARRAY.splice( i, 1);\r
4123                                                 sortComicElement();\r
4124                                                 _comicElement.$.stop().css( {\r
4125                                                         filter:         '',\r
4126                                                         opacity:        ''\r
4127                                                 }).fadeOut( function(){\r
4128                                                         this.parentNode.removeChild( this);\r
4129                                                 });\r
4130                                                 currentElement = currentElement === _comicElement ? null : currentElement;\r
4131                                                 return;\r
4132                                         }\r
4133                                 }\r
4134                         }\r
4135                         function restoreComicElement( arg){\r
4136                                 var isAppend = arg[ 0],\r
4137                                         comicElement = arg[ 1];\r
4138                                 isAppend === true ? appendComicElement( comicElement) : removeComicElement( comicElement);\r
4139                         }\r
4140                         /*\r
4141                          * DRAGGABLE_ELEMENT_ARRAY の順番を基準に、zの再計算\r
4142                          * jqElmの並び替え。\r
4143                          */\r
4144                         function sortComicElement(){\r
4145                                 var l = DRAGGABLE_ELEMENT_ARRAY.length,\r
4146                                         _comicElement, jqElm, jqNext;\r
4147                                 for( var i=NUM_RESIZER; i < l; ++i){\r
4148                                         _comicElement = DRAGGABLE_ELEMENT_ARRAY[ i];\r
4149                                         jqElm = _comicElement.$;\r
4150                                         jqNext && jqNext.before( jqElm);\r
4151                                         _comicElement.z = l -i -NUM_RESIZER +1;\r
4152                                         jqNext = jqElm;\r
4153                                 }\r
4154                         }\r
4155                         function replaceComicElement( _comicElement, goForward){\r
4156                                 // DRAGGABLE_ELEMENT_ARRAYの再構築\r
4157                                 var l = DRAGGABLE_ELEMENT_ARRAY.length,\r
4158                                         i = ( function(){\r
4159                                                 for( var ret = NUM_RESIZER; ret < l; ++ret){\r
4160                                                         if( DRAGGABLE_ELEMENT_ARRAY[ ret] === _comicElement) return ret;\r
4161                                                 }\r
4162                                                 return -1;\r
4163                                         })();\r
4164                                 if( i === -1) return;\r
4165                                 if( goForward === true){\r
4166                                         if( i === NUM_RESIZER) return;\r
4167                                         DRAGGABLE_ELEMENT_ARRAY.splice( i, 1);\r
4168                                         DRAGGABLE_ELEMENT_ARRAY.splice( i -1, 0, _comicElement);\r
4169                                 } else {\r
4170                                         if( i === l -1) return;\r
4171                                         DRAGGABLE_ELEMENT_ARRAY.splice( i, 1);\r
4172                                         DRAGGABLE_ELEMENT_ARRAY.splice( i +1, 0, _comicElement);\r
4173                                 }\r
4174                                 sortComicElement();\r
4175                         }\r
4176                         function restoreReplaceObject( arg){\r
4177                                 replaceComicElement( arg[ 0], arg[ 1]);\r
4178                         }\r
4179                         \r
4180                         return {\r
4181                                 init: function(){\r
4182                                 /*\r
4183                                  * Resizer\r
4184                                  */                                     \r
4185                                         PANEL_RESIZER_TOP.init();\r
4186                                         PANEL_RESIZER_BOTTOM.init();\r
4187                                 /*\r
4188                                  * comic-element\r
4189                                  */\r
4190                                         comicElementContainer = $( '#comic-element-container');\r
4191                                         \r
4192                                         appendComicElement( ImageElementClass.apply( {}, [ 'images/13.gif', 'penchan', 10, 10, 0, 100, 140, 0]));\r
4193                                         appendComicElement( TextElementClass.apply( {}, [ 0, 270, 'Hello', 50, 70, 1, 200, 160, 1]));\r
4194                                         \r
4195                                         COMIC_ELEMENT_OPERATOR.init( updateMouseCursor);\r
4196                                 /*\r
4197                                  * \r
4198                                  */\r
4199                                         log = $( '#operation-catcher-log');\r
4200 \r
4201                                         resize();\r
4202                                         log.html( 'vector' +h2c.balloon.enabled());\r
4203                                         delete COMIC_ELEMENT_CONTROL.init;\r
4204                                 },\r
4205                                 resize: resize,\r
4206                                 onMouseMove: function( _mouseX, _mouseY){\r
4207                                         var l = DRAGGABLE_ELEMENT_ARRAY.length,\r
4208                                                 _X = _mouseX -( _canvasX || canvasX),\r
4209                                                 _Y = _mouseY -( _canvasY || canvasY),\r
4210                                                 _elm, _x, _y;\r
4211                                                 \r
4212                                         if( currentElement !== null && currentElement.busy() === true){\r
4213                                                 currentElement.onMouseMove( _X, _Y);\r
4214                                                 return true;\r
4215                                         }\r
4216                                         if( currentElement !== null){\r
4217                                                 _x = currentElement.hitareaX();\r
4218                                                 _y = currentElement.hitareaY();\r
4219                                                 if( _x <= _X && _y <= _Y && _x + currentElement.hitareaW() >= _X && _y +currentElement.hitareaH() >= _Y){\r
4220                                                         currentElement.onMouseMove( _X, _Y); // cursor\r
4221                                                         return true;\r
4222                                                 }\r
4223                                         }\r
4224                                         for( var i=0; i<l; i++){\r
4225                                                 _elm = DRAGGABLE_ELEMENT_ARRAY[ i];\r
4226                                                 _x = _elm.hitareaX();\r
4227                                                 _y = _elm.hitareaY();\r
4228                                                 // hitTest\r
4229                                                 if( _x <= _X && _y <= _Y && _x + _elm.hitareaW() >= _X && _y +_elm.hitareaH() >= _Y){\r
4230                                                         currentElement = _elm;\r
4231                                                         currentElement.onMouseMove( _X, _Y); // cursor\r
4232                                                         log.html( [ _X, _Y, _x, _y, i].join( ','));\r
4233                                                         return true;\r
4234                                                 }\r
4235                                         }\r
4236                                         currentElement = null;                                                  \r
4237                                         COMIC_ELEMENT_OPERATOR.hide();\r
4238                                         log.html( [ _X, _Y, _x, _y].join( ','));\r
4239                                         return false;\r
4240                                 },\r
4241                                 onMouseUp: function( _mouseX, _mouseY){\r
4242                                         var ret = currentElement !== null && currentElement.busy() === true;\r
4243                                         ret === true && currentElement.onMouseUp( _mouseX -_canvasX || canvasX, _mouseY -_canvasY || canvasY);\r
4244                                         _canvasX = _canvasY = NaN;\r
4245                                         return ret;\r
4246                                 },\r
4247                                 onMouseDown: function( _mouseX, _mouseY){\r
4248                                         _canvasX = canvasX;\r
4249                                         _canvasY = canvasY;\r
4250                                         currentElement !== null && currentElement.onMouseDown( _mouseX -canvasX, _mouseY -canvasY);\r
4251                                         return currentElement !== null;\r
4252                                 },\r
4253                                 onMouseClick: function( _mouseX, _mouseY){\r
4254                                         return currentElement !== null &&\r
4255                                                 currentElement !== PANEL_RESIZER_TOP &&\r
4256                                                 currentElement !== PANEL_RESIZER_BOTTOM &&\r
4257                                                 COMIC_ELEMENT_OPERATOR.onMouseClick( _mouseX -canvasX, _mouseY -canvasY);\r
4258                                 },\r
4259                                 onMouseOut: function( _mouseX, _mouseY){\r
4260                                         currentElement !== null && currentElement.busy() === true && currentElement.onMouseUp( _mouseX -canvasX, _mouseY -canvasY);\r
4261                                         _canvasX = _canvasY = NaN;\r
4262                                         currentElement = null;\r
4263                                         COMIC_ELEMENT_OPERATOR.hide();\r
4264                                         return false;\r
4265                                 },\r
4266                                 busy: function(){\r
4267                                         return currentElement !== null ? currentElement.busy() : false;\r
4268                                 },\r
4269                                 createImageElement: function( url, imagesetID, x, y, z, w, h){\r
4270                                         w = w || 200; //ActualWidth\r
4271                                         h = h || 150; //ActualHeight\r
4272                                         x = x || Math.floor( canvasW /2 -w /2);\r
4273                                         y = y || Math.floor( canvasH /2 -h /2);\r
4274                                         IMAGE_GROUP_EXPROLER.show( function( _url, _w, _h){\r
4275                                                 var _comicElement = ImageElementClass.apply( {}, [ _url, imagesetID, x, y, z || -1, w, h, DRAGGABLE_ELEMENT_ARRAY.length -NUM_RESIZER]);\r
4276                                                 appendComicElement( _comicElement);\r
4277                                                 _comicElement.animate( undefined, undefined, _w, _h);\r
4278                                                 SAVE( restoreComicElement, [ false, _comicElement], [ true, _comicElement], true);\r
4279                                         });\r
4280                                 },\r
4281                                 createTextElement: function( type, angle, text, x, y, z, w, h){\r
4282                                         type = type || 0;\r
4283                                         angle = angle || 0;\r
4284                                         text = text || '';\r
4285                                         w = w || 200;\r
4286                                         h = h || 150;\r
4287                                         x = x || Math.floor( canvasW /2 -w /2 +Math.random() *10);\r
4288                                         y = y || Math.floor( canvasH /2 -h /2 +Math.random() *10);\r
4289                                         var _comicElement = TextElementClass.apply( {}, [ type, angle, text, x, y, z || -1, w, h, DRAGGABLE_ELEMENT_ARRAY.length -NUM_RESIZER]);\r
4290                                         TEXT_EDITOR_CONTROL.show( _comicElement, function( _comicElement){\r
4291                                                 appendComicElement( _comicElement);\r
4292                                                 SAVE( restoreComicElement, [ false, _comicElement], [ true, _comicElement], true);\r
4293                                         });\r
4294                                 },\r
4295                                 getAsHTML: function( isAbsoluteUrl, isXHTML){\r
4296                                         var HTML_ARRAY = [],\r
4297                                                 l = DRAGGABLE_ELEMENT_ARRAY.length,\r
4298                                                 _timing = 0,\r
4299                                                 _comicElement;\r
4300 \r
4301                                         while( HTML_ARRAY.length < l -NUM_RESIZER){\r
4302                                                 _comicElement = getComicElementByTiming();\r
4303                                                 if( _comicElement === null) break;\r
4304                                                 HTML_ARRAY.push( _comicElement.getAsHTML( isAbsoluteUrl, isXHTML));\r
4305                                         }\r
4306                                         function getComicElementByTiming(){\r
4307                                                 while( _timing < l *2){\r
4308                                                         for(var i=NUM_RESIZER; i<l; ++i){\r
4309                                                                 if( _timing === DRAGGABLE_ELEMENT_ARRAY[ i].timing){\r
4310                                                                         ++_timing;\r
4311                                                                         return DRAGGABLE_ELEMENT_ARRAY[ i];\r
4312                                                                 }\r
4313                                                         }\r
4314                                                         ++_timing;\r
4315                                                 }\r
4316                                                 return null;\r
4317                                         }\r
4318                                         HTML_ARRAY.unshift(\r
4319                                                 [\r
4320                                                         '<div class="panel" ',\r
4321                                                                 'style="',\r
4322                                                                         'height:', canvasH, 'px;',\r
4323                                                                         'background-color:', ';',\r
4324                                                                 '"',\r
4325                                                         '>'\r
4326                                                 ].join( '')\r
4327                                         );              \r
4328                                         HTML_ARRAY.push( '</div>');\r
4329                                         \r
4330                                         return HTML_ARRAY.join( h2c.LINE_FEED_CODE_TEXTAREA);\r
4331                                 },\r
4332                                 getAsJsonString: function(){\r
4333                                         var JSON_STRING_ARRAY = [],\r
4334                                                 IMAGE_ARRAY = [],\r
4335                                                 BALLOON_ARRAY = [],\r
4336                                                 l = DRAGGABLE_ELEMENT_ARRAY.length,\r
4337                                                 _timing = 0,\r
4338                                                 _comicElement,\r
4339                                                 cr = h2c.LINE_FEED_CODE_TEXTAREA;\r
4340                                                 \r
4341                                         while( IMAGE_ARRAY.length + BALLOON_ARRAY.length < l -NUM_RESIZER){\r
4342                                                 _comicElement = getComicElementByTiming();\r
4343                                                 if( _comicElement === null) break;\r
4344                                                 _comicElement.type === COMIC_ELEMENT_TYPE_IMAGE ? \r
4345                                                         IMAGE_ARRAY.push( _comicElement.getAsJsonString()) :\r
4346                                                         BALLOON_ARRAY.push( _comicElement.getAsJsonString());\r
4347                                         }\r
4348                                         function getComicElementByTiming(){\r
4349                                                 while( _timing < l *2){\r
4350                                                         for(var i=NUM_RESIZER; i<l; ++i){\r
4351                                                                 if( _timing === DRAGGABLE_ELEMENT_ARRAY[ i].timing){\r
4352                                                                         ++_timing;\r
4353                                                                         return DRAGGABLE_ELEMENT_ARRAY[ i];\r
4354                                                                 }\r
4355                                                         }\r
4356                                                         ++_timing;\r
4357                                                 }\r
4358                                                 return null;\r
4359                                         }\r
4360                                         return [\r
4361                                                 '{', cr,\r
4362                                                         '"panel": {', cr,\r
4363                                                             '"border": 1,', cr,\r
4364                                                             '"comic_id": 5,', cr,\r
4365                                                             '"resource_picture_id": 1,', cr,\r
4366                                                             '"width": ', canvasW, ',', cr,\r
4367                                                             '"height": ', canvasH, ',', cr,\r
4368                                                             '"panel_pictures_attributes": {', cr,\r
4369                                                                 IMAGE_ARRAY.join( ',' +cr), cr,\r
4370                                                             '},', cr,\r
4371                                                             '"balloons_attributes": {', cr,\r
4372                                                                 BALLOON_ARRAY.join( ',' +cr), cr,\r
4373                                                             '}', cr,\r
4374                                                         '}', cr,\r
4375                                                 '}'\r
4376                                         ].join( '');\r
4377                                 }\r
4378                         }\r
4379                 })( resize);\r
4380         \r
4381         /*\r
4382          * \r
4383          */\r
4384                 function resize( isResizerTopAction){\r
4385                         GRID_CONTROL.resize();\r
4386                         WHITE_GLASS_CONTROL.resize();\r
4387                         PANEL_BORDER_CONTROL.resize();\r
4388                         COMIC_ELEMENT_CONTROL.resize( isResizerTopAction);\r
4389                 }\r
4390                 return {\r
4391                         init: function( _canvasW, _canvasH){\r
4392                                 canvasW = _canvasW || DEFAULT_PANEL_WIDTH;\r
4393                                 canvasH = _canvasH || DEFAULT_PANEL_HEIGHT;\r
4394                                 canvasX = Math.floor( ( windowW -canvasW) /2);\r
4395                                 canvasY = Math.floor( ( windowH -canvasH) /2);\r
4396                                 \r
4397                                 GRID_CONTROL.init();\r
4398                                 // WHITE_GLASS_CONTROL.init();\r
4399                                 PANEL_BORDER_CONTROL.init();\r
4400                                 COMIC_ELEMENT_CONTROL.init();\r
4401                                 \r
4402                                 resize();\r
4403                                 \r
4404                                 h2c.key.addKeyUpdateEvent( h2c.view.EDITOR, 32, false, false, function( e){\r
4405                                         if( e.type === 'keyup'){\r
4406                                                 currentListener === null && COMIC_ELEMENT_CONTROL.busy() === false && updateMouseCursor( '');   \r
4407                                                 isCanvasDraggble = false;\r
4408                                         } else {\r
4409                                                 currentListener === null && COMIC_ELEMENT_CONTROL.busy() === false && updateMouseCursor( 'move');\r
4410                                                 isCanvasDraggble = true;\r
4411                                         }\r
4412                                 });\r
4413                                 delete CANVAS_CONTROL.init;\r
4414                         },\r
4415                         x: function(){ return canvasX;},\r
4416                         y: function(){ return canvasY;},\r
4417                         onWindowResize: function( _windowW, _windowH){\r
4418                                 canvasX = Math.floor(( _windowW - canvasW) / 2);\r
4419                                 canvasY = Math.floor(( _windowH - canvasH) / 2);\r
4420                                 resize();\r
4421                         },\r
4422                         onMouseMove: function( _mouseX, _mouseY){\r
4423                                 if( currentListener === null && COMIC_ELEMENT_CONTROL.busy() === false && isCanvasDraggble === true && isDragging === true){\r
4424                                         canvasX = startCanvasX +_mouseX -xOffset;\r
4425                                         canvasY = startCanvasY +_mouseY -yOffset;\r
4426                                         resize();\r
4427                                 } else {\r
4428                                         COMIC_ELEMENT_CONTROL.onMouseMove( _mouseX, _mouseY)\r
4429                                 }\r
4430                         },\r
4431                         onMouseUp: function( _mouseX, _mouseY){\r
4432                                 if( COMIC_ELEMENT_CONTROL.onMouseUp( _mouseX, _mouseY) === false && isCanvasDraggble === true){\r
4433                                         isDragging = false;\r
4434                                         updateMouseCursor( '');\r
4435                                 }\r
4436                         },\r
4437                         onMouseDown: function( _mouseX, _mouseY){\r
4438                                 if( COMIC_ELEMENT_CONTROL.onMouseDown( _mouseX, _mouseY) === false && isCanvasDraggble === true){\r
4439                                         xOffset = _mouseX;\r
4440                                         yOffset = _mouseY;\r
4441                                         startCanvasX = canvasX;\r
4442                                         startCanvasY = canvasY;\r
4443                                         isDragging = true;\r
4444                                         updateMouseCursor( 'move');\r
4445                                 }\r
4446                         },\r
4447                         onMouseClick: function( _mouseX, _mouseY){\r
4448                                 COMIC_ELEMENT_CONTROL.onMouseClick( _mouseX, _mouseY)\r
4449                         },\r
4450                         onMouseOut: function( _mouseX, _mouseY){\r
4451                                 if( COMIC_ELEMENT_CONTROL.onMouseOut( _mouseX, _mouseY) === false){\r
4452                                         \r
4453                                 }\r
4454                         },\r
4455                         busy: function(){\r
4456                                 return isDragging === true || COMIC_ELEMENT_CONTROL.busy();\r
4457                         },\r
4458                         createImageElement: function( url, imagesetID, x, y, z, w, h){\r
4459                                 COMIC_ELEMENT_CONTROL.createImageElement( url, imagesetID, x, y, z, w, h);\r
4460                         },\r
4461                         createTextElement: function( type, angle, text, x, y, w, h, z){\r
4462                                 COMIC_ELEMENT_CONTROL.createTextElement( type, angle, text, x, y, w, h, z);\r
4463                         },\r
4464                         getAsHTML: COMIC_ELEMENT_CONTROL.getAsHTML,\r
4465                         getAsJsonString: COMIC_ELEMENT_CONTROL.getAsJsonString\r
4466                 }\r
4467         })();\r
4468 \r
4469 \r
4470         function updateMouseCursor( _cursor){\r
4471                 if( currentCursor !== _cursor){\r
4472                         currentCursor = _cursor;\r
4473                         setTimeout(\r
4474                                 function(){\r
4475                                         ELM_MOUSE_EVENT_CHATCHER.style.cursor = _cursor;\r
4476                                 }, 0\r
4477                         );\r
4478                 }\r
4479         }\r
4480         function centering(){\r
4481                 h2c.editor.onWindowResize( windowW, windowH);\r
4482         }       \r
4483         function mouseEventRellay( rellayMethod, e){\r
4484                 var _mouseX = e.pageX,\r
4485                         _mouseY = e.pageY;\r
4486                 if( currentListener !== null && currentListener.busy() === true){\r
4487                         currentListener[ rellayMethod]( _mouseX, _mouseY);\r
4488                 } else {\r
4489                         currentListener = null;\r
4490                         var l = MOUSE_LISTENER_ARRAY.length,\r
4491                                 _listener;\r
4492                         for( var i=0; i<l; ++i){\r
4493                                 _listener = MOUSE_LISTENER_ARRAY[ i];\r
4494                                 if( typeof _listener[ rellayMethod] === 'function' && _listener[ rellayMethod]( _mouseX, _mouseY) === true){\r
4495                                         currentListener = _listener;\r
4496                                         break;\r
4497                                 }\r
4498                         }\r
4499                 }\r
4500                 e.stopPropagation();\r
4501                 return false;\r
4502         }\r
4503 \r
4504         return {\r
4505                 init: function(){\r
4506                         var jqWindow = h2c.jqWindow();\r
4507                         windowW = jqWindow.width();\r
4508                         windowH = jqWindow.height();\r
4509                         \r
4510                         jqEditor = $( '#editor');\r
4511 \r
4512                         h2c.key.addKeyDownEvent( h2c.view.EDITOR, 96, false, true, centering);\r
4513                         h2c.key.addKeyDownEvent( h2c.view.EDITOR, 48, false, true, centering);\r
4514 \r
4515                         HISTORY.init();\r
4516                         MENU_BAR_CONTROL.EDIT.createSelection( 'centering', 'ctrl + 0', centering, true, true, true);\r
4517                         \r
4518                         WINDOWS_CONTROL.init();\r
4519                         CANVAS_CONTROL.init();\r
4520                         \r
4521                         // last\r
4522                         MENU_BAR_CONTROL.init();\r
4523                         \r
4524                         TEXT_EDITOR_CONTROL.init();\r
4525                         IMAGE_GROUP_EXPROLER.init();\r
4526                 /*\r
4527                  * jqMouseEventChacher は透明な要素で、\r
4528                  * マウスイベントをcurrentElement(currentElement)に伝えるのが仕事\r
4529                  * このような実装になるのは、ここの表示オブジェクトにイベントを設定した場合、表示が追いつかずマウスカーソルが外れたタイミングでイベントが終わってしまうため。\r
4530                  */\r
4531                 /*\r
4532                  * MOUSE_LISTENER_ARRAY は、表示順に格納.手前の要素が最初\r
4533                  * MENU_BAR_CONTROL,\r
4534                  * WINDOW_CONTROL,\r
4535                  * CANVAS_CONTROL\r
4536                  * .busy() === true なら、そのままonMouseMove()にイベントを流す.これはArrayの後ろから、奥の表示要素から\r
4537                  * onMouseMove()に流してみて、false が帰れば、次にリスナーにも流す.\r
4538                  */\r
4539                         MOUSE_LISTENER_ARRAY.push( MENU_BAR_CONTROL, WINDOWS_CONTROL, CANVAS_CONTROL);\r
4540                         \r
4541                         jqMouseEventChacher = $( ELM_MOUSE_EVENT_CHATCHER)\r
4542                                 .mousemove( function( e){\r
4543                                         return mouseEventRellay( 'onMouseMove', e);\r
4544                                 }).mousedown( function( e){\r
4545                                         return mouseEventRellay( 'onMouseDown', e);\r
4546                                 }).mouseup( function( e){\r
4547                                         return mouseEventRellay( 'onMouseUp', e);\r
4548                                 }).mouseout( function( e){\r
4549                                         return mouseEventRellay( 'onMouseUp', e);\r
4550                                 }).click( function( e){\r
4551                                         var _mouseX = e.pageX,\r
4552                                                 _mouseY = e.pageY;\r
4553                                         if( CANVAS_CONTROL.busy() === true || WINDOWS_CONTROL.onMouseClick( _mouseX, _mouseY) === false){\r
4554                                                 CANVAS_CONTROL.onMouseClick( _mouseX, _mouseY);\r
4555                                         }\r
4556                                         e.stopPropagation();\r
4557                                         return false;\r
4558                                 }).css( {\r
4559                                         height: windowH // ie6\r
4560                                 });\r
4561                         \r
4562                         delete h2c.editor.init;\r
4563                 },\r
4564                 onWindowResize: function( _windowW, _windowH){\r
4565                         windowW = _windowW;\r
4566                         windowH = _windowH;\r
4567                         \r
4568                         /*\r
4569                          * ieは +'px'が不要みたい\r
4570                          */\r
4571                         jqEditor.get( 0).style.height = _windowH +'px';\r
4572                         ELM_MOUSE_EVENT_CHATCHER.style.height = _windowH +'px';\r
4573                         \r
4574                         WINDOWS_CONTROL.onWindowResize( _windowW, _windowH);\r
4575                         MENU_BAR_CONTROL.onWindowResize( _windowW, _windowH);\r
4576                         CANVAS_CONTROL.onWindowResize( _windowW, _windowH);\r
4577                 },\r
4578                 MIN_WIDTH:      320,\r
4579                 MIN_HEIGHT:     320\r
4580         }\r
4581 })();\r
4582 \r
4583 h2c.log = ( function(){\r
4584         return {\r
4585                 init: function(){}\r
4586         }\r
4587 })();\r
4588 \r
4589 h2c.io = ( function(){\r
4590         \r
4591         return {\r
4592                 init: function(){}\r
4593         }\r
4594 })();\r
4595 \r
4596 \r
4597 /*\r
4598  * 画像一覧は\r
4599  *      お気に入り画像一覧 > tag:ペン次郎 > ペン次郎:笑う\r
4600  *  最近アップロードされた画像 > images\r
4601  *  最近使われた画像 > images\r
4602  *  キャラクター画像庫 > アニマル系 > tag:ペン次郎 > ペン次郎:笑う\r
4603  *  風景画像庫 >\r
4604  *  効果画像庫 >\r
4605  *  アイテム画像庫 >\r
4606  *  \r
4607  * 画像一覧を読み込むタイミング\r
4608  */\r
4609 h2c.file = ( function(){\r
4610         var TREE_TYPE_IS_COMIC = 1,\r
4611                 TREE_TYPE_IS_IMAGE = 2,\r
4612                 TREE_TYPE_IS_SETTING = 3,\r
4613                 TREE_TYPE_IS_HELP = 4,\r
4614                 FILE_TYPE_IS_FOLDER = 1,\r
4615                 FILE_TYPE_IS_IMAGE = 2,\r
4616                 FILE_TYPE_IS_PANEL = 3,\r
4617                 FILE_TYPE_IS_SETTING = 4,\r
4618                 FILE_TYPE_IS_HTML = 5,\r
4619                 FILE_STATE_IS_UNKNOWN = 0,\r
4620                 FILE_STATE_IS_OK = 1,\r
4621                 FILE_STATE_IS_LOADING = 2,\r
4622                 FILE_STATE_IS_ERROR = 3,\r
4623                 FILE_STATE_IS_BROKEN = 4,\r
4624                 TREE_EVENT_UPDTE = 'onUpdate',\r
4625                 FILE_EVENT_UPDATED_ATTRIVUTE = 'onUpdate',\r
4626                 FILE_EVENT_GET_SEQENTIAL_FILES = 'gotSeqentilFiles',\r
4627                 ROLE_IS_SUPER_USER = 2^4,\r
4628                 ROLE_IS_OWNER = 2^3,\r
4629                 ROLE_IS_CREATOR = 2^2,\r
4630                 ROLE_IS_ARTIST = 2^1,\r
4631                 ROLE_IS_VISITOR = 2^0,\r
4632                 ROLE_IS_UNKROWN = 2^-1,\r
4633                 UPDATE_POLICY_SOCAV = 0x11111,// s: super user\r
4634                 UPDATE_POLICY_SOCA_ = 0x11110,// o: owner( comic || panel || picture )\r
4635                 UPDATE_POLICY_SOC__ = 0x11100,// c: creator\r
4636                 UPDATE_POLICY_SO_A_ = 0x11010,// a: artist\r
4637                 UPDATE_POLICY_SO___ = 0x11000,// v: visitor\r
4638                 UPDATE_POLICY__O___ = 0x01000,// l: lisence manager\r
4639                 UPDATE_POLICY_S____ = 0x10000,\r
4640                 UPDATE_POLICY______ = 0x00000,\r
4641                 FILEDATA_RESITER = [],\r
4642                 FILEDATA_ACCESS = [];\r
4643                 \r
4644         var REQUEST_CONTROLER = ( function(){\r
4645                 var REQUEST_TICKET_RESISTER = [],\r
4646                         DATA_IS_JSON = 1;\r
4647                 \r
4648                 var RequestTicketClass = ( function(){\r
4649                         \r
4650                 })();\r
4651                 \r
4652                 return {\r
4653                         init: function(){\r
4654                                 delete REQUEST_CONTROLER.init;\r
4655                         },\r
4656                         getJson: function( _url, _onLoad, _onError){\r
4657                                 REQUEST_TICKET_RESISTER.push( RequestTicketClass.apply( {}, [ _url, _onLoad, _onError]));\r
4658                         }\r
4659                 }\r
4660         })();\r
4661         /* ----------------------\r
4662          * folder\r
4663          *  name\r
4664          *  file [],\r
4665          *  ID( imgGroupID, comicID)\r
4666          * ----------------------\r
4667          * \r
4668          * img-group(folder)\r
4669          *  name - rename,\r
4670          *  groupID,\r
4671          *  img []\r
4672          *  author, licence,\r
4673          *  create, update\r
4674          * \r
4675          * img\r
4676          *  name - rename\r
4677          *  src(id)\r
4678          *  groupID - updateGropuID\r
4679          *  actualWidth, actualHeight,\r
4680          *  author, licence( 'by,no-resize'),\r
4681          *  create, update, tag,\r
4682          *  actualWidth, actualHeight\r
4683          * \r
4684          * ----------------------\r
4685          * \r
4686          * comic\r
4687          *  id\r
4688          *  name - rename\r
4689          *  width\r
4690          *  editmode\r
4691          *  panel []\r
4692          *  \r
4693          * panel\r
4694          *  comicID,\r
4695          *  seqno,\r
4696          *      height,\r
4697          *  border,\r
4698          *  elments [\r
4699          *    height,\r
4700          *    bg-color,\r
4701          *    bg-image,\r
4702          *    bg-position,\r
4703          *    bg-repeate,\r
4704          *    border,  \r
4705          *  ]\r
4706          *  \r
4707          * ----------------------\r
4708          */\r
4709         var FILE_CONTROLER = ( function(){\r
4710                 var FILE_EVENT_LISTENER_RESISTER = [],\r
4711                         TREE_ACCESS = [];\r
4712 \r
4713                 var TreeClass = function( TREE_ROOTFILE){\r
4714                         var UID = TREE_ACCESS.length,\r
4715                                 currentFile = TREE_ROOTFILE,\r
4716                                 PARENT_FILE_RESITER = [],\r
4717                                 ACCESS = {\r
4718                                         fileEventChatcher:      dispatchFileEvent,\r
4719                                         destroy:                        onDestroy\r
4720                                 };\r
4721                         \r
4722                         function dispatchFileEvent( fileEvent){\r
4723                                 \r
4724                         }\r
4725                         function onDestroy(){\r
4726                                 \r
4727                         }\r
4728                         \r
4729                         TREE_ACCESS.push( ACCESS);\r
4730                         \r
4731                         FILE_CONTROLER.getSeqentialFiles( currentFile);\r
4732                         return {\r
4733                                 ROOT_FILE :function(){\r
4734                                         return TREE_ROOTFILE;\r
4735                                 },\r
4736                                 currentFile: function(){\r
4737                                         return currentFile;\r
4738                                 },\r
4739                                 hierarky: function(){\r
4740                                         return PARENT_FILE_RESITER.length;\r
4741                                 },\r
4742                                 down: function( _index){\r
4743                                         if( typeof _index !== 'number' || _index < 0 || _index >= currentFile.getChildFileLength()) return;\r
4744                                         PARENT_FILE_RESITER.unshift( currentFile);\r
4745                                         currentFile = currentFile.getChildFileByIndex( _index);\r
4746                                         FILE_CONTROLER.getSeqentialFiles( currentFile);\r
4747                                         return currentFile;\r
4748                                 },\r
4749                                 up: function(){\r
4750                                         if( PARENT_FILE_RESITER.length === 0) return;\r
4751                                         currentFile = PARENT_FILE_RESITER.shift();\r
4752                                         FILE_CONTROLER.getSeqentialFiles( currentFile);\r
4753                                         return currentFile;\r
4754                                 },\r
4755                                 addEventListener: function( UID, _eventType, _callback){\r
4756                                         FILE_CONTROLER.addEventListener( UID, _eventType, _callback);\r
4757                                 },\r
4758                                 removeEventListener: function( UID, _eventType, _callback){\r
4759                                         FILE_CONTROLER.removeEventListener( UID, _eventType, _callback);\r
4760                                 },\r
4761                                 createSearchResultFolder: function( _searchParam){\r
4762                                         \r
4763                                 },\r
4764                                 destroySearchResultFolder: function( _searchParam){\r
4765                                         \r
4766                                 },\r
4767                                 destroy: function(){\r
4768                                         FILE_CONTROLER.destroyTree( UID);\r
4769                                 }\r
4770                         }\r
4771                 };\r
4772 \r
4773                 var FileEventTicketClass = function( UID, _eventType, _callback){\r
4774                         return {\r
4775                                 fileUID:        UID,\r
4776                                 eventType:      _eventType,\r
4777                                 callBack:       _callback\r
4778                         }\r
4779                 }\r
4780                 \r
4781                 var FileEventClass = function( eventType, file, key, value){\r
4782                         return {\r
4783                                 eventType:                      eventType,\r
4784                                 targetFile:                     file,\r
4785                                 updatedAttribute:       key,\r
4786                                 updatedValue:           value\r
4787                         }\r
4788                 }\r
4789 \r
4790                 function disptchFileEvent( eventType, fileUID, key, value){\r
4791                         var _fileEvent = FileEventClass.apply( {}, [ eventType, fileUID, key, value]),\r
4792                                 l = TREE_ACCESS.length,\r
4793                                 _tree;\r
4794                         for( var i=0; i<l; ++i){\r
4795                                 _tree = TREE_ACCESS[ i];\r
4796                                 _tree !== null && _tree.fileEventChatcher( _fileEvent);\r
4797                         }\r
4798                 }\r
4799                 function getFileDataAccess( UIDorFILE){\r
4800                         var l = FILEDATA_ACCESS.length,\r
4801                                 i = typeof UIDorFILE === 'number' ?\r
4802                                                 ( UIDorFILE > 0 && UIDorFILE > l ? UIDorFILE : -1) :\r
4803                                                 ( function(){\r
4804                                                         for( var i=0; i<l; ++i){\r
4805                                                                 if( FILEDATA_ACCESS[ i] === UIDorFILE) return i;\r
4806                                                         }\r
4807                                                         return -1;\r
4808                                                 })();\r
4809                         return i !== -1 ? FILEDATA_ACCESS[ i] : null;\r
4810                 }\r
4811                 \r
4812                 return {\r
4813                         init: function(){\r
4814                                 delete FILE_CONTROLER.init;\r
4815                         },\r
4816                         createTree: function( _rootFileData){\r
4817                                 return TreeClass.apply( {}, [ _rootFileData]);\r
4818                         },\r
4819                         getFileData: function( _file){\r
4820                                 var _access = getFileDataAccess( _file);\r
4821                                 return _access !== null ? _access.DATA : null;\r
4822                         },\r
4823                         getSeqentialFiles: function( _uid){\r
4824 \r
4825                         },\r
4826                         updateFileAttribute: function( _uid, key, _value, _opt_callback){\r
4827                                 var _fileData = getFileDataAccess( _uid),\r
4828                                         _type = _fileData.TYPE;\r
4829                                 \r
4830                         },                      \r
4831                         getFileAttribute: function( _uid, KEYorKEYARRAY){\r
4832                                 var _fileData = getFileDataAccess( _uid),\r
4833                                         _type = _fileData.TYPE;\r
4834                         },\r
4835                         move: function( _prentUID, _targetfile, _newFolder, _newIndex, _opt_callback){\r
4836                                 var _parentData = getFileDataAccess( _prentUID),\r
4837                                         _parentType = _parentData.TYPE,\r
4838                                         _targetData =  getFileDataAccess( _targetfile),\r
4839                                         _targetType = _targetData.TYPE;\r
4840                         },\r
4841                         replace: function( _uid, _file, _newIndex){\r
4842                                 \r
4843                         }\r
4844                 }\r
4845         })();\r
4846         \r
4847         /*\r
4848          * fileのdataはobjectで保持している。\r
4849          * h2c.file.の外からファイルをみるときは、FileClassを通して操作する。\r
4850          * fileの変更、それに付随して追加されたイベントは、treeで管理される。\r
4851          * treeがdestryされると、fileのイベントリスナーも全て削除される。\r
4852          */\r
4853         \r
4854         var FileClass = function( TREE, PARENT_FILE, DATA){\r
4855                 var TYPE = DATA.type,\r
4856                         UID = FILEDATA_ACCESS.length,\r
4857                         CHILDREN = DATA.children;\r
4858                 \r
4859                 FILEDATA_ACCESS.push(\r
4860                         {\r
4861                                 TYPE:           TYPE,\r
4862                                 DATA:           DATA,\r
4863                                 CHILDREN:       CHILDREN,\r
4864                                 destroy:        function(){\r
4865                                                                 PARENT_FILE = DATA = CHILDREN = null;\r
4866                                                                 delete this.destroy;\r
4867                                                         }\r
4868                         }\r
4869                 );\r
4870                 return {\r
4871                         TYPE: function(){ return TYPE;},\r
4872                         state: function(){\r
4873                                 return DATA.state !== undefined ? DATA.state : FILE_STATE_IS_OK;\r
4874                         },\r
4875                         childFileLength: function(){\r
4876                                 return typeof CHILDREN === 'array' ? CHILDREN.length : 0;\r
4877                         },\r
4878                         getChildFileByIndex: function( _index){\r
4879                                 if( typeof _index !== 'number' || _index < 0 || typeof CHILDREN !== 'array' || _index >= CHILDREN.length) return;\r
4880                                 return FileClass.apply( {}, [ TREE, PARENT_FILE, this, CHILDREN[ _index]]);\r
4881                         },\r
4882                         getChildFileIndex: function( _FILEorFILEDATA){\r
4883                                 if( typeof CHILDREN !== 'array') return -1;\r
4884                                 var l = CHILDREN.length,\r
4885                                         _fileData = ( function(){\r
4886                                                 var l = FILEDATA_RESITER.length;\r
4887                                                 for( var i=0; i<l; ++i){\r
4888                                                         if( _FILEorFILEDATA === FILEDATA_RESITER[ i]) return _FILEorFILEDATA;\r
4889                                                 }\r
4890                                                 return FILE_CONTROLER.getFileData( _FILEorFILEDATA);\r
4891                                         })();\r
4892                                 if( _fileData === null) return -1;\r
4893                                 for( var i=0; i<l; ++i){\r
4894                                         if( CHILDREN[ i] === _fileData) return i;\r
4895                                 }\r
4896                                 return -1;\r
4897                         },\r
4898                         isChildFile: function( _FILEorFILEDATA){\r
4899                                 return this.getChildFileIndex( _FILEorFILEDATA) !== -1;\r
4900                         },                      \r
4901                         getAttribute: function( KEYorKEYARRAY){\r
4902                                 return FILE_CONTROLER.getFileAttribute( UID, KEYorKEYARRAY);\r
4903                         },\r
4904                         getSeqentialFiles: function(){\r
4905                                 FILE_CONTROLER.getSeqentialFiles( this);\r
4906                         },\r
4907                         updateAttribute: function( key, value, opt_callback){\r
4908                                 TREE.updateFileAttribute( UID, key, value, opt_callback);\r
4909                         },\r
4910                         move: function( _newFolder, _newIndex, opt_callback){\r
4911                                 TREE.move( PARENT_FILE, UID, _newFolder, _newIndex, opt_callback);\r
4912                         },\r
4913                         replace: function( _newIndex, opt_callback){\r
4914                                 TREE.replace( PARENT_FILE, UID, _newIndex, opt_callback);\r
4915                         },\r
4916                         addEventListener: function( _eventType, _callback){\r
4917                                 TREE.addEventListener( UID, _eventType, _callback);\r
4918                         },\r
4919                         removeEventListener: function( _eventType, _callback){\r
4920                                 TREE.removeEventListener( UID, _eventType, _callback);\r
4921                         }\r
4922                 }\r
4923         };\r
4924         \r
4925         var ROOT_FILEDATA = {\r
4926                         name:           'root',\r
4927                         type:           FILE_TYPE_IS_FOLDER,\r
4928                         children:       []\r
4929                 },\r
4930                 IMAGE_FILEDATA = {\r
4931                         name:           'image root',\r
4932                         type:           FILE_TYPE_IS_FOLDER\r
4933                 },\r
4934                 COMIC_FILEDATA = {\r
4935                         name:           'comic root',\r
4936                         type:           FILE_TYPE_IS_FOLDER\r
4937                 },\r
4938                 SETTING_FILEDATA = {\r
4939                         name:           'setting root',\r
4940                         type:           FILE_TYPE_IS_FOLDER\r
4941                 },\r
4942                 HELP_FILEDATA = {\r
4943                         name:           'help root',\r
4944                         type:           FILE_TYPE_IS_FOLDER\r
4945                 };\r
4946         FILEDATA_RESITER.push( ROOT_FILEDATA, IMAGE_FILEDATA, COMIC_FILEDATA, SETTING_FILEDATA, HELP_FILEDATA);\r
4947         ROOT_FILEDATA.children.push( IMAGE_FILEDATA, COMIC_FILEDATA, SETTING_FILEDATA, HELP_FILEDATA);\r
4948 \r
4949         var SYSTEM_TREE = FILE_CONTROLER.createTree( FileClass.apply( {}, [ null, null, ROOT_FILEDATA])),\r
4950                 ROOT_FILE = SYSTEM_TREE.ROOT_FILE(),\r
4951                 COMIC_ROOT_INDEX = ROOT_FILE.getChildFileByIndex( COMIC_FILEDATA),\r
4952                 COMIC_ROOT_FILE = ROOT_FILE.getChildFileByIndex( COMIC_ROOT_INDEX),\r
4953                 IMAGE_ROOT_INDEX = ROOT_FILE.getChildFileByIndex( IMAGE_FILEDATA),\r
4954                 IMAGE_ROOT_FILE = ROOT_FILE.getChildFileByIndex( IMAGE_ROOT_INDEX),             \r
4955                 SETTING_ROOT_INDEX = ROOT_FILE.getChildFileByIndex( SETTING_FILEDATA),\r
4956                 SETTING_ROOT_FILE = ROOT_FILE.getChildFileByIndex( SETTING_ROOT_INDEX),\r
4957                 HELP_ROOT_INDEX = ROOT_FILE.getChildFileByIndex( HELP_FILEDATA),\r
4958                 HELP_ROOT_FILE = ROOT_FILE.getChildFileByIndex( HELP_ROOT_INDEX);\r
4959 \r
4960         return {\r
4961                 init: function(){\r
4962                         REQUEST_CONTROLER.init();\r
4963                         FILE_CONTROLER.init();\r
4964                         delete h2c.file.init;\r
4965                 },\r
4966                 createTree: function( _treeType){\r
4967                         var _rootFile;\r
4968                         if( _treeType === TREE_TYPE_IS_COMIC) _rootFile = COMIC_ROOT_FILE;\r
4969                         if( _treeType === TREE_TYPE_IS_IMAGE) _rootFile = IMAGE_ROOT_FILE;\r
4970                         if( _treeType === TREE_TYPE_IS_SETTING) _rootFile = SETTING_ROOT_FILE;\r
4971                         if( _treeType === TREE_TYPE_IS_HELP) _rootFile = HELP_ROOT_FILE;\r
4972                         if( _rootFile === undefined) return;\r
4973                         return FILE_CONTROLER.createTree( _rootFile);\r
4974                 },\r
4975                 TREE_TYPE_IS_COMIC:             TREE_TYPE_IS_COMIC,\r
4976                 TREE_TYPE_IS_IMAGE:             TREE_TYPE_IS_IMAGE,\r
4977                 TREE_TYPE_IS_SETTING:   TREE_TYPE_IS_SETTING,\r
4978                 FILE_TYPE_IS_FOLDER:    FILE_TYPE_IS_FOLDER,\r
4979                 FILE_TYPE_IS_IMAGE:             FILE_TYPE_IS_IMAGE,\r
4980                 FILE_TYPE_IS_PANEL:             FILE_TYPE_IS_PANEL,\r
4981                 FILE_TYPE_IS_SETTING:   FILE_TYPE_IS_SETTING\r
4982         }\r
4983 })();\r
4984 \r
4985 // i18n\r
4986 // login\r
4987 // lib\r
4988 \r
4989 h2c.fn( h2c.view);\r
4990 h2c.fn( h2c.overlay);\r
4991 h2c.fn( h2c.key);\r
4992 h2c.fn( h2c.balloon);\r
4993 h2c.fn( h2c.editor);\r
4994 h2c.fn( h2c.file);\r
4995 \r
4996 $(window).ready( h2c.init);\r