1 /****************************************************************************
  2  Copyright (c) 2010-2012 cocos2d-x.org
  3  Copyright (c) 2008-2010 Ricardo Quesada
  4  Copyright (c) 2011      Zynga Inc.
  5 
  6  http://www.cocos2d-x.org
  7 
  8  Permission is hereby granted, free of charge, to any person obtaining a copy
  9  of this software and associated documentation files (the "Software"), to deal
 10  in the Software without restriction, including without limitation the rights
 11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 12  copies of the Software, and to permit persons to whom the Software is
 13  furnished to do so, subject to the following conditions:
 14 
 15  The above copyright notice and this permission notice shall be included in
 16  all copies or substantial portions of the Software.
 17 
 18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 24  THE SOFTWARE.
 25  ****************************************************************************/
 26 
 27 /**
 28  * copy an new object
 29  * @function
 30  * @param {object|Array} obj source object
 31  * @return {Array|object}
 32  */
 33 cc.clone = function (obj) {
 34     // Cloning is better if the new object is having the same prototype chain
 35     // as the copied obj (or otherwise, the cloned object is certainly going to
 36     // have a different hidden class). Play with C1/C2 of the
 37     // PerformanceVirtualMachineTests suite to see how this makes an impact
 38     // under extreme conditions.
 39     //
 40     // Object.create(Object.getPrototypeOf(obj)) doesn't work well because the
 41     // prototype lacks a link to the constructor (Carakan, V8) so the new
 42     // object wouldn't have the hidden class that's associated with the
 43     // constructor (also, for whatever reasons, utilizing
 44     // Object.create(Object.getPrototypeOf(obj)) + Object.defineProperty is even
 45     // slower than the original in V8). Therefore, we call the constructor, but
 46     // there is a big caveat - it is possible that the this.init() in the
 47     // constructor would throw with no argument. It is also possible that a
 48     // derived class forgets to set "constructor" on the prototype. We ignore
 49     // these possibities for and the ultimate solution is a standardized
 50     // Object.clone(<object>).
 51     var newObj = (obj.constructor) ? new obj.constructor : {};
 52 
 53         // Assuming that the constuctor above initialized all properies on obj, the
 54     // following keyed assignments won't turn newObj into dictionary mode
 55     // becasue they're not *appending new properties* but *assigning existing
 56     // ones* (note that appending indexed properties is another story). See
 57     // CCClass.js for a link to the devils when the assumption fails.
 58     for (var key in obj) {
 59         var copy = obj[key];
 60         // Beware that typeof null == "object" !
 61         if (((typeof copy) == "object") && copy &&
 62             !(copy instanceof cc.Node) && !(copy instanceof HTMLElement)) {
 63             newObj[key] = cc.clone(copy);
 64         } else {
 65             newObj[key] = copy;
 66         }
 67     }
 68     return newObj;
 69 };
 70 
 71 /**
 72  * Function added for JS bindings compatibility. Not needed in cocos2d-html5.
 73  * @function
 74  * @param {object} jsObj subclass
 75  * @param {object} superclass
 76  */
 77 cc.associateWithNative = function (jsObj, superclass) {
 78 };
 79 
 80 /**
 81  * Is show bebug info on web page
 82  * @constant
 83  * @type {Boolean}
 84  */
 85 cc.IS_SHOW_DEBUG_ON_PAGE = cc.IS_SHOW_DEBUG_ON_PAGE || false;
 86 
 87 cc._logToWebPage = function (message) {
 88     var logList = document.getElementById("logInfoList");
 89     if (!logList) {
 90         var logDiv = document.createElement("Div");
 91         logDiv.setAttribute("id", "logInfoDiv");
 92         cc.canvas.parentNode.appendChild(logDiv);
 93         logDiv.setAttribute("width", "200");
 94         logDiv.setAttribute("height", cc.canvas.height);
 95         logDiv.style.zIndex = "99999";
 96         logDiv.style.position = "absolute";
 97         logDiv.style.top = "0";
 98         logDiv.style.left = "0";
 99 
100         logList = document.createElement("ul");
101         logDiv.appendChild(logList);
102         logList.setAttribute("id", "logInfoList");
103         logList.style.height = cc.canvas.height + "px";
104         logList.style.color = "#fff";
105         logList.style.textAlign = "left";
106         logList.style.listStyle = "disc outside";
107         logList.style.fontSize = "12px";
108         logList.style.fontFamily = "arial";
109         logList.style.padding = "0 0 0 20px";
110         logList.style.margin = "0";
111         logList.style.textShadow = "0 0 3px #000";
112         logList.style.zIndex = "99998";
113         logList.style.position = "absolute";
114         logList.style.top = "0";
115         logList.style.left = "0";
116         logList.style.overflowY = "hidden";
117 
118         var tempDiv = document.createElement("Div");
119         logDiv.appendChild(tempDiv);
120         tempDiv.style.width = "200px";
121         tempDiv.style.height = cc.canvas.height + "px";
122         tempDiv.style.opacity = "0.1";
123         tempDiv.style.background = "#fff";
124         tempDiv.style.border = "1px solid #dfdfdf";
125         tempDiv.style.borderRadius = "8px";
126     }
127     var addMessage = document.createElement("li");
128     //var now = new Date();
129     //addMessage.innerHTML = now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds() + " " + now.getMilliseconds() + " " + message;
130     addMessage.innerHTML = message;
131     if (logList.childNodes.length == 0) {
132         logList.appendChild(addMessage);
133     } else {
134         logList.insertBefore(addMessage, logList.childNodes[0]);
135     }
136 };
137 
138 /**
139  * Output Debug message.
140  * @function
141  * @param {String} message
142  */
143 cc.log = function (message) {
144     if (!cc.IS_SHOW_DEBUG_ON_PAGE) {
145         console.log.apply(console, arguments);
146     } else {
147         cc._logToWebPage(message);
148     }
149 };
150 
151 /**
152  * Pop out a message box
153  * @param {String} message
154  * @function
155  */
156 cc.MessageBox = function (message) {
157     console.log(message);
158 };
159 
160 /**
161  * Output Assert message.
162  * @function
163  * @param {Boolean} cond If cond is false, assert.
164  * @param {String} message
165  */
166 cc.Assert = function (cond, message) {
167     if (console.assert)
168         console.assert(cond, message);
169     else {
170         if (!cond) {
171             if (message)
172                 alert(message);
173         }
174     }
175 };
176 
177 /**
178  * Update Debug setting.
179  * @function
180  */
181 cc.initDebugSetting = function () {
182     // cocos2d debug
183     if (cc.COCOS2D_DEBUG == 0) {
184         cc.log = function () {
185         };
186         cc.logINFO = function () {
187         };
188         cc.logERROR = function () {
189         };
190         cc.Assert = function () {
191         };
192     } else if (cc.COCOS2D_DEBUG == 1) {
193         cc.logINFO = cc.log;
194         cc.logERROR = function () {
195         };
196     } else if (cc.COCOS2D_DEBUG > 1) {
197         cc.logINFO = cc.log;
198         cc.logERROR = cc.log;
199     }// COCOS2D_DEBUG
200 };
201 
202 // Enum the language type supportted now
203 /**
204  * English language code
205  * @constant
206  * @type Number
207  */
208 cc.LANGUAGE_ENGLISH = 0;
209 
210 /**
211  * Chinese language code
212  * @constant
213  * @type Number
214  */
215 cc.LANGUAGE_CHINESE = 1;
216 
217 /**
218  * French language code
219  * @constant
220  * @type Number
221  */
222 cc.LANGUAGE_FRENCH = 2;
223 
224 /**
225  * Italian language code
226  * @constant
227  * @type Number
228  */
229 cc.LANGUAGE_ITALIAN = 3;
230 
231 /**
232  * German language code
233  * @constant
234  * @type Number
235  */
236 cc.LANGUAGE_GERMAN = 4;
237 
238 /**
239  * Spanish language code
240  * @constant
241  * @type Number
242  */
243 cc.LANGUAGE_SPANISH = 5;
244 
245 /**
246  * Russian language code
247  * @constant
248  * @type Number
249  */
250 cc.LANGUAGE_RUSSIAN = 6;
251 
252 /**
253  * Korean language code
254  * @constant
255  * @type Number
256  */
257 cc.LANGUAGE_KOREAN = 7;
258 
259 /**
260  * Japanese language code
261  * @constant
262  * @type Number
263  */
264 cc.LANGUAGE_JAPANESE = 8;
265 
266 /**
267  * Hungarian language code
268  * @constant
269  * @type Number
270  */
271 cc.LANGUAGE_HUNGARIAN = 9;
272 
273 /**
274  * Portuguese language code
275  * @constant
276  * @type Number
277  */
278 cc.LANGUAGE_PORTUGUESE = 10;
279 
280 /**
281  * Arabic language code
282  * @constant
283  * @type Number
284  */
285 cc.LANGUAGE_ARABIC = 11;
286 
287 /**
288  * Norwegian language code
289  * @constant
290  * @type Number
291  */
292 cc.LANGUAGE_NORWEGIAN = 12;
293 
294 /**
295  * Polish language code
296  * @constant
297  * @type Number
298  */
299 cc.LANGUAGE_POLISH = 13;
300 
301 /**
302  * keymap
303  * @example
304  * //Example
305  * //to mark a keydown
306  * cc.keyDown[65] = true;
307  * //or
308  * cc.keyMap[cc.KEY.a]
309  *
310  * //to mark a keyup
311  * do cc.keyDown[65] = false;
312  *
313  * //to find out if a key is down, check
314  * if(cc.keyDown[65])
315  * //or
316  * if,(cc.keyDown[cc.KEY.space])
317  * //if its undefined or false or null, its not pressed
318  * @constant
319  * @type object
320  */
321 cc.KEY = {
322     backspace:8,
323     tab:9,
324     enter:13,
325     shift:16, //should use shiftkey instead
326     ctrl:17, //should use ctrlkey
327     alt:18, //should use altkey
328     pause:19,
329     capslock:20,
330     escape:27,
331     pageup:33,
332     pagedown:34,
333     end:35,
334     home:36,
335     left:37,
336     up:38,
337     right:39,
338     down:40,
339     insert:45,
340     Delete:46,
341     0:48,
342     1:49,
343     2:50,
344     3:51,
345     4:52,
346     5:53,
347     6:54,
348     7:55,
349     8:56,
350     9:57,
351     a:65,
352     b:66,
353     c:67,
354     d:68,
355     e:69,
356     f:70,
357     g:71,
358     h:72,
359     i:73,
360     j:74,
361     k:75,
362     l:76,
363     m:77,
364     n:78,
365     o:79,
366     p:80,
367     q:81,
368     r:82,
369     s:83,
370     t:84,
371     u:85,
372     v:86,
373     w:87,
374     x:88,
375     y:89,
376     z:90,
377     num0:96,
378     num1:97,
379     num2:98,
380     num3:99,
381     num4:100,
382     num5:101,
383     num6:102,
384     num7:103,
385     num8:104,
386     num9:105,
387     '*':106,
388     '+':107,
389     '-':109,
390     'numdel':110,
391     '/':111,
392     f1:112, //f1-f12 dont work on ie
393     f2:113,
394     f3:114,
395     f4:115,
396     f5:116,
397     f6:117,
398     f7:118,
399     f8:119,
400     f9:120,
401     f10:121,
402     f11:122,
403     f12:123,
404     numlock:144,
405     scrolllock:145,
406     semicolon:186,
407     ',':186,
408     equal:187,
409     '=':187,
410     ';':188,
411     comma:188,
412     dash:189,
413     '.':190,
414     period:190,
415     forwardslash:191,
416     grave:192,
417     '[':219,
418     openbracket:219,
419     ']':221,
420     closebracket:221,
421     backslash:220,
422     quote:222,
423     space:32
424 };
425 
426 
427 /**
428  * Image Format:JPG
429  * @constant
430  * @type Number
431  */
432 cc.FMT_JPG = 0;
433 
434 /**
435  * Image Format:PNG
436  * @constant
437  * @type Number
438  */
439 cc.FMT_PNG = 1;
440 
441 /**
442  * Image Format:TIFF
443  * @constant
444  * @type Number
445  */
446 cc.FMT_TIFF = 2;
447 
448 /**
449  * Image Format:RAWDATA
450  * @constant
451  * @type Number
452  */
453 cc.FMT_RAWDATA = 3;
454 
455 /**
456  * Image Format:WEBP
457  * @constant
458  * @type Number
459  */
460 cc.FMT_WEBP = 4;
461 
462 /**
463  * Image Format:UNKNOWN
464  * @constant
465  * @type Number
466  */
467 cc.FMT_UNKNOWN = 5;
468 
469 cc.getImageFormatByData = function (imgData) {
470 	// if it is a png file buffer.
471 	if (imgData.length > 8) {
472 		if (imgData[0] == 0x89
473 			&& imgData[1] == 0x50
474 			&& imgData[2] == 0x4E
475 			&& imgData[3] == 0x47
476 			&& imgData[4] == 0x0D
477 			&& imgData[5] == 0x0A
478 			&& imgData[6] == 0x1A
479 			&& imgData[7] == 0x0A) {
480 			return cc.FMT_PNG;
481 		}
482 	}
483 
484 	// if it is a tiff file buffer.
485 	if (imgData.length > 2) {
486 		if ((imgData[0] == 0x49 && imgData[1] == 0x49)
487 			|| (imgData[0] == 0x4d && imgData[1] == 0x4d)
488 			|| (imgData[0] == 0xff && imgData[1] == 0xd8)) {
489 			return cc.FMT_TIFF;
490 		}
491 	}
492 
493 	return cc.FMT_UNKNOWN;
494 };
495 
496 
497 
498 var CCNS_REG1 = /^\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*$/;
499 var CCNS_REG2 = /^\s*\{\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*,\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*\}\s*$/
500 /**
501  * Returns a Core Graphics rectangle structure corresponding to the data in a given string. <br/>
502  * The string is not localized, so items are always separated with a comma. <br/>
503  * If the string is not well-formed, the function returns cc.RectZero.
504  * @function
505  * @param {String} content content A string object whose contents are of the form "{{x,y},{w, h}}",<br/>
506  * where x is the x coordinate, y is the y coordinate, w is the width, and h is the height. <br/>
507  * These components can represent integer or float values.
508  * @return {cc.Rect} A Core Graphics structure that represents a rectangle.
509  * Constructor
510  * @example
511  * // example
512  * var rect = cc.RectFromString("{{3,2},{4,5}}");
513  */
514 cc.RectFromString = function (content) {
515 	var result = CCNS_REG2.exec(content);
516 	if(!result) return cc.RectZero();
517 	return cc.rect(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]), parseFloat(result[4]));
518 };
519 
520 /**
521  * Returns a Core Graphics point structure corresponding to the data in a given string.
522  * @function
523  * @param {String} content   A string object whose contents are of the form "{x,y}",
524  * where x is the x coordinate and y is the y coordinate.<br/>
525  * The x and y values can represent integer or float values. <br/>
526  * The string is not localized, so items are always separated with a comma.<br/>
527  * @return {cc.Point} A Core Graphics structure that represents a point.<br/>
528  * If the string is not well-formed, the function returns cc.PointZero.
529  * Constructor
530  * @example
531  * //example
532  * var point = cc.PointFromString("{3.0,2.5}");
533  */
534 cc.PointFromString = function (content) {
535 	var result = CCNS_REG1.exec(content);
536 	if(!result) return cc.PointZero();
537 	return cc.p(parseFloat(result[1]), parseFloat(result[2]));
538 };
539 
540 /**
541  * Returns a Core Graphics size structure corresponding to the data in a given string.
542  * @function
543  * @param {String} content   A string object whose contents are of the form "{w, h}",<br/>
544  * where w is the width and h is the height.<br/>
545  * The w and h values can be integer or float values. <br/>
546  * The string is not localized, so items are always separated with a comma.<br/>
547  * @return {cc.Size} A Core Graphics structure that represents a size.<br/>
548  * If the string is not well-formed, the function returns cc.SizeZero.
549  * @example
550  * // example
551  * var size = cc.SizeFromString("{3.0,2.5}");
552  */
553 cc.SizeFromString = function (content) {
554 	var result = CCNS_REG1.exec(content);
555 	if(!result) return cc.SizeZero();
556 	return cc.size(parseFloat(result[1]), parseFloat(result[2]));
557 };
558 
559 /**
560  *
561  * @param {Function} selector
562  * @param {cc.Node} target
563  * @param {Object|Number|String} data
564  */
565 cc.doCallback = function (selector, target, data) {
566     if(!selector)
567         return ;
568     if (target && (typeof(selector) == "string")) {
569         target[selector](data);
570     } else if (target && (typeof(selector) == "function")) {
571         selector.call(target, data);
572     } else {
573         selector(data);
574     }
575 };