text: jui.define("util.math", [], function() {
  
  	/**
  	 * @class util.math
  	 *
  	 * Math Utility
  	 *
  	 * @singleton
  	 */
  	var self = {
  
  		/**
  		 * @method rotate
  		 *
  		 * 2d rotate
  		 *
  		 * @param {Number} x
  		 * @param {Number} y
  		 * @param {Number} radian	roate 할 radian
  		 * @return {Object}
  		 * @return {Number} return.x  변환된 x
  		 * @return {Number} return.y  변환된 y
  		 *
   		 */
  		rotate : function(x, y, radian) {
  			return {
  				x : x * Math.cos(radian) - y * Math.sin(radian),
  				y : x * Math.sin(radian) + y * Math.cos(radian)
  			}
  		},
  
  		resize : function(maxWidth, maxHeight, objectWidth, objectHeight) {
  			var ratio = objectHeight / objectWidth;
  
  			if (objectWidth >= maxWidth && ratio <= 1) {
  				objectWidth = maxWidth;
  				objectHeight = maxHeight * ratio;
  			} else if (objectHeight >= maxHeight) {
  				objectHeight = maxHeight;
  				objectWidth = maxWidth / ratio;
  			}
  
  			return { width : objectWidth, height : objectHeight};
  		},
  
  		/**
  		 * @method radian
  		 *
  		 * convert degree to radian
  		 *
  		 * @param {Number} degree
  		 * @return {Number} radian
  		 */
  		radian : function(degree) {
  			return degree * Math.PI / 180;
  		},
  
  		/**
  		 * @method degree
  		 *
  		 * convert radian to degree
  		 *
  		 * @param {Number} radian
  		 * @return {Number} degree
  		 */
  		degree : function(radian) {
  			return radian * 180 / Math.PI;
  		},
  
          angle : function(x1, y1, x2, y2) {
              var dx = x2 - x1,
                  dy = y2 - y1;
  
              return Math.atan2(dy, dx);
          },
  
  		/**
  		 * @method interpolateNumber
  		 *
  		 * a, b 의 중간값 계산을 위한 callback 함수 만들기
  		 *
  		 * @param {Number} a	first value
  		 * @param {Number} b 	second value
  		 * @return {Function}
  		 */
  		interpolateNumber : function(a, b) {
              var dist = (b - a);
  			return function(t) {
  				return a + dist * t;
  			}
  		},
  
  		// 중간값 round 해서 계산하기
  		interpolateRound : function(a, b) {
  
              var dist = (b - a);
              return function(t) {
                  return Math.round(a + dist * t);
              }
  		},
  
  		/**
  		 * 특정 구간의 값을 자동으로 계산 
  		 * 
  		 * @param {Object} min
  		 * @param {Object} max
  		 * @param {Object} ticks
  		 * @param {Object} isNice
  		 */
  		nice : function(min, max, ticks, isNice) {
  			isNice = isNice || false;
  
  			if (min > max) {
  				var _max = min;
  				var _min = max;
  			} else {
  				var _min = min;
  				var _max = max;
  			}
  
  			var _ticks = ticks;
  			var _tickSpacing = 0;
  			var _range = [];
  			var _niceMin;
  			var _niceMax;
  
  			function niceNum(range, round) {
  				var exponent = Math.floor(Math.log(range) / Math.LN10);
  				var fraction = range / Math.pow(10, exponent);
  				var nickFraction;
  
  				//console.log(range, exponent, fraction, _ticks);
  
  				if (round) {
  					if (fraction < 1.5)
  						niceFraction = 1;
  					else if (fraction < 3)
  						niceFraction = 2;
  					else if (fraction < 7)
  						niceFraction = 5;
  					else
  						niceFraction = 10;
  				} else {
  					if (fraction <= 1)
  						niceFraction = 1;
  					else if (fraction <= 2)
  						niceFraction = 2;
  					else if (fraction <= 5)
  						niceFraction = 5;
  					else
  						niceFraction = 10;
  
  					//console.log(niceFraction)
  				}
  
  				return niceFraction * Math.pow(10, exponent);
  
  			}
  
  			function caculate() {
  				_range = (isNice) ? niceNum(_max - _min, false) : _max - _min;
  				_tickSpacing = (isNice) ? niceNum(_range / _ticks, true) : _range / _ticks;
  				_niceMin = (isNice) ? Math.floor(_min / _tickSpacing) * _tickSpacing : _min;
  				_niceMax = (isNice) ? Math.floor(_max / _tickSpacing) * _tickSpacing : _max;
  			}
  
  			caculate();
  
  			return {
  				min : _niceMin,
  				max : _niceMax,
  				range : _range,
  				spacing : _tickSpacing
  			}
  		}		
  	}
  
  	return self;
  });
  