/**
 * helpers.js
 *
 * A variety of helper functions and class extensions for general purpose use.
 *
 * @author Justen Robertson <justen@justenrobertson.com>
 * @link http://www.justenrobertson.com
 * @license Free (no restrictions, no rights reserved)
 */





/**
 * function mkCurve
 *
 * Builds a curve string for use in a path. Useful for dynamically generating
 * the string so we can pass it to an animation.
 */
function mkCurve(coords, type) {
	var str = (type?type:"C");
	coords.each(function(coord) {
		if (typeof coord == 'string') str = str +" "+coord;
		else str = str+" "+coord.x+","+coord.y;
	});
	return str;
}




/**
 * function dec2hex
 *
 * Converts a decimal to hex value.
 */
function dec2hex(d) {return d.toString(16);}




/**
 * function hex2dec
 *
 * Converts a hexadecimal to decimal value.
 */

function hex2dec(h) {return parseInt(h,16);}




/**
 * function r2d
 *
 * Converts radian to degrees
 */

function r2d(deg) {
	return deg*(360/(2*Math.PI));
}




/**
 * function d2r
 *
 * Converts degrees to radians
 */
function d2r(rad) {
	return rad*((2*Math.PI)/360);
}




/**
 * function rndColor()
 *
 * Creates a random color as a hex string.
 */
function rndColor() {
	var r = dec2hex(parseInt(255*Math.random()));
	var g = dec2hex(parseInt(255*Math.random()));
	var b = dec2hex(parseInt(255*Math.random()));
	while (r.length<2) r = "0"+r; // pad it out to 2 places
	while (g.length<2) g = "0"+g;
	while (b.length<2) b = "0"+b;

	return "#"+r+g+b;
}




/**
 * inArray method for arrays, similar to in_array in PHP
 */
Array.prototype.inArray = function (value) {
// Returns true if the passed value is found in the
// array. Returns false if it is not.
	var i;
	for (i=0; i < this.length; i++) {
		// Matches identical (===), not just similar (==).
		if (this[i] === value) {
			return true;
		}
	}
	return false;
}




/**
 * array.each() useful little function
 */
Array.prototype.each = function(code) {
  for(i=0;i<this.length;i++){
    code(this[i]);
  }
};




Array.prototype.count = function() {
	var count = 0;
  for(i=0;i<this.length;i++){
    if(this[i] !== undefined) count++;
  }
	return count;
};




/**
 * function bin2dec converts a binary to decimal number
 */
function bin2dec(num) {return parseInt(num, 2);}


/**
 * function dec2bin converts a decimal to binary number
 */
function dec2bin(num) {return num.toString(2);}


/**
 * function bin2hex converts a binary to hexadecimal number
 */
function bin2hex(num) {return parseInt(num, 2).toString(16);}


/**
 * function hex2bin converts a hexadecimal to binary number
 */
function hex2bin(num) {return parseInt(num, 16).toString(2);}


/**
 * function toCurrency converts a float to a currency format (xxx.xx)
 */
function toCurrency(mnt) {
    mnt -= 0;
    mnt = (Math.round(mnt*100))/100;
    return (mnt == Math.floor(mnt)) ? mnt + '.00'
              : ( (mnt*10 == Math.floor(mnt*10)) ?
                       mnt + '0' : mnt);
}

/**
 * function fNum makes a number with commas for easy reading
 */
function fNum(nStr)
{
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}


/**
 * Jacked from http://www.raphaeljs.com; a basic spinner for wait dialogs
 * Slight modifications for use locally
 */
function Spinner(paper, R1, R2, count, stroke_width, colour) {
		var sectorsCount = count || 12,
				color = colour || "#fff",
				width = stroke_width || 15,
				r1 = Math.min(R1, R2) || 35,
				r2 = Math.max(R1, R2) || 60,
				r = paper,
				cx = r2 + width,
				cy = r2 + width,

				sectors = [],
				opacity = [],
				beta = 2 * Math.PI / sectorsCount,

				pathParams = {stroke: color, "stroke-width": width, "stroke-linecap": "round"};
				Raphael.getColor.reset();
		for (var i = 0; i < sectorsCount; i++) {
				var alpha = beta * i - Math.PI / 2,
						cos = Math.cos(alpha),
						sin = Math.sin(alpha);
				opacity[i] = 1 / sectorsCount * i;
				sectors[i] = r.path(pathParams)
												.moveTo(cx + r1 * cos + paper.width/2, cy + r1 * sin + paper.height/2)
												.lineTo(cx + r2 * cos + paper.width/2, cy + r2 * sin + paper.height/2);
				if (color == "rainbow") {
						sectors[i].attr("stroke", Raphael.getColor());
				}
		}
		var tick;
		(function ticker() {
				opacity.unshift(opacity.pop());
				for (var i = 0; i < sectorsCount; i++) {
						sectors[i].attr("opacity", opacity[i]);
				}
				r.safari();
				tick = setTimeout(ticker, 1000 / sectorsCount);
		})();
		return function () {
				clearTimeout(tick);
				sectors.each(function(s){s.remove();});
		};
}