Number.prototype.round = function(decs) {
	decs = force_int(decs);
	var val = this.valueOf();
	
	var factor = Math.pow(10,decs);
	return Math.round(val*factor)/factor;
}



function force_int(val) {
	val = (val=='' || val==null) ? '0' : val.toString(); 
	val = val.replace(/[^\-\d\.]+/g, '');
	val = (val=='' || val==null) ? 0 : val; 
	val = parseInt(val);
	return val;
}

function force_float(val, dec, fixed) {
	dec = (dec=='' || dec==null) ? -1 : parseInt(dec);
	
	val = (val=='' || val==null) ? '0' : val.toString(); 
	val = val.replace(/[^\-\d\.]+/g, '');
	val = (val=='' || val==null) ? 0 : val; 
	val = parseFloat(val);
	
	if(dec != -1) {
		val = (fixed) ? val.toFixed(dec) : val.round(dec);
	}
	
	return val;
}






function is_type(e, type) {
	type = (type == '') ? 'String' : type;
	return Object.prototype.toString.call(e) === '[object '+type+']'; 
}



function num_to_unix(amt) {
	var dec = (g_decimal==',') ? '\,' : '\\.';
	var pat = new RegExp("[^\\-\\d"+dec+"]+", "g");
	amt = amt.toString();
	
	amt = amt.replace(pat, '');
	amt = amt.replace(/,/g, '.');
	amt = parseFloat(amt);
	return amt;
}

function add_commas (value) {
	value = value.toString();
	var pattern = /^(\-?\d+)(\d{3})/g;
	
	value = value.replace(/\.+/g, 'xxx');
	while(value.match(pattern)!=null) {
		value = value.replace(pattern, "$1"+g_comma+"$2");
	}
	value = value.replace(/xxx/g, g_decimal);
	
	return value;
}



Number.prototype.num_to_unix = function() {	
	var dec = (g_decimal==',') ? '\,' : '\\.';
	var pat = new RegExp("[^\\-\\d"+dec+"]+", "g");
	var amt = this.valueOf().toString();
	
	amt = amt.replace(pat, '');
	amt = amt.replace(/,/g, '.');
	amt = parseFloat(amt);
	return amt;
}

Number.prototype.add_commas = function() {
	value = this.valueOf().toString();
	var pattern = /^(\-?\d+)(\d{3})/g;
	
	value = value.replace(/\.+/g, 'xxx');
	while(value.match(pattern)!=null) {
		value = value.replace(pattern, "$1"+g_comma+"$2");
	}
	value = value.replace(/xxx/g, g_decimal);
	
	return value;
}








function is_type(e, type) {
	type = (type == '') ? 'String' : type;
	return Object.prototype.toString.call(e) === '[object '+type+']'; 
}


Date.prototype.getDayName = function(short){
	var day = this.getDay();
	var days = (short) ? new Array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat') : new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
	return days[day];
}
Date.prototype.getUTCDayName = function(short){
	var day = this.getUTCDay();
	var days = (short) ? new Array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat') : new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
	return days[day];
}
Date.prototype.getMonthName = function(short){
	var month = this.getMonth();
	var months = (short) ? new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec') : new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
	return months[month];
}
Date.prototype.getUTCMonthName = function(short){
	var month = this.getUTCMonth();
	var months = (short) ? new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec') : new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
	return months[month];
}

function trunc(val) {
	var val = (val < 0) ? Math.ceil(val) : Math.floor(val);
	return val;
}
function leading_zero(val) {
	if(val < 10) {
		return '0'+val;
	}
	return val;
}
function toSecs(val) {
	val = val/1000;
	val = (val > 0) ? Math.floor(val) : Math.ceil(val);
	return val;
}
function toMilli(val) {
	val = val*1000;
	return val;
}
function fHour(hours, minutes) {
	return leading_zero(hours)+':'+leading_zero(minutes);
}
function mHour(hours, minutes) {
	var mer = 'am';
	if(hours == 0) {
		hours = 12;
	} else if(hours > 12) {
		hours -= 12;
		mer = 'pm';
	}
	
	return hours+':'+leading_zero(minutes)+mer;
}
function pretty_offset(val) {
	var sign = (val < 0) ? '-' : '+';
	val = Math.abs(val);
	
	var hour = trunc(val/3600);
	var minutes = (val-hour*3600)/60;
	
	return sign+leading_zero(hour)+':'+leading_zero(minutes);
}
























function trunc(g) {
	//C code expects an integer arithmetic to do truncation, i.e. just return the quotient
	if (g>0){return Math.floor(g)}else{return Math.ceil(g)} 
}
function sun_position(udtLocationdLatitude, udtLocationdLongitude, date) {
	if(!is_type(date, 'Date')) {
		date = new Date();
	}
	
	// setup the input variables
	udtTimeiYear = date.getUTCFullYear();
	udtTimeiMonth = date.getUTCMonth()+1;
	udtTimeiDay = date.getUTCDate();
	udtTimedHours = date.getUTCHours();
	udtTimedMinutes = date.getUTCMinutes();
	udtTimedSeconds = date.getUTCSeconds();
	
	
	pi =3.14159265358979323846
	twopi=(2*pi)
	rad=(pi/180)
	dEarthMeanRadius=6371.01	// In km
	dAstronomicalUnit=149597890	// In km
	dDecimalHours = udtTimedHours + (udtTimedMinutes + udtTimedSeconds / 60.0 ) / 60.0;
	// Calculate current Julian Day not use of trunc since Javascript doesn't support div for integters like C++
	liAux1 =trunc((udtTimeiMonth-14)/12);
	liAux2=trunc((1461*(udtTimeiYear + 4800 + liAux1))/4) + trunc((367*(udtTimeiMonth - 2-12*liAux1))/12)- trunc((3*trunc((udtTimeiYear + 4900 + liAux1)/100))/4)+udtTimeiDay-32075;
	dJulianDate=(liAux2)-0.5+dDecimalHours/24.0;
	dElapsedJulianDays = dJulianDate-2451545.0;
	dOmega=2.1429-0.0010394594*dElapsedJulianDays;
	dMeanLongitude = 4.8950630+ 0.017202791698*dElapsedJulianDays; // Radians
	dMeanAnomaly = 6.2400600+ 0.0172019699*dElapsedJulianDays;
	dEclipticLongitude = dMeanLongitude + 0.03341607*Math.sin( dMeanAnomaly ) + 0.00034894*Math.sin( 2*dMeanAnomaly )-0.0001134 -0.0000203*Math.sin(dOmega);
	dEclipticObliquity = 0.4090928 - 6.2140e-9*dElapsedJulianDays +0.0000396*Math.cos(dOmega);
	dSin_EclipticLongitude= Math.sin( dEclipticLongitude );
	dY = Math.cos( dEclipticObliquity ) * dSin_EclipticLongitude;
	dX = Math.cos( dEclipticLongitude );
	dRightAscension = Math.atan2( dY,dX );
	if( dRightAscension < 0.0 ) dRightAscension = dRightAscension + twopi;
	dDeclination = Math.asin( Math.sin( dEclipticObliquity )*dSin_EclipticLongitude );
	dGreenwichMeanSiderealTime = 6.6974243242 + 0.0657098283*dElapsedJulianDays + dDecimalHours;
	dLocalMeanSiderealTime = (dGreenwichMeanSiderealTime*15 + udtLocationdLongitude)*rad;
	dHourAngle = dLocalMeanSiderealTime - dRightAscension;
	dLatitudeInRadians = udtLocationdLatitude*rad;
	dCos_Latitude = Math.cos( dLatitudeInRadians );
	dSin_Latitude = Math.sin( dLatitudeInRadians );
	dCos_HourAngle= Math.cos( dHourAngle );
	udtSunCoordinatesdZenithAngle = (Math.acos( dCos_Latitude*dCos_HourAngle*Math.cos(dDeclination) + Math.sin( dDeclination )*dSin_Latitude));
	dY = -Math.sin( dHourAngle );
	dX = Math.tan( dDeclination )*dCos_Latitude - dSin_Latitude*dCos_HourAngle;
	udtSunCoordinatesdAzimuth = Math.atan2( dY, dX );
	if ( udtSunCoordinatesdAzimuth < 0.0 ) 
		udtSunCoordinatesdAzimuth = udtSunCoordinatesdAzimuth + twopi;
	udtSunCoordinatesdAzimuth = udtSunCoordinatesdAzimuth/rad;
	dParallax=(dEarthMeanRadius/dAstronomicalUnit)*Math.sin(udtSunCoordinatesdZenithAngle);
	udtSunCoordinatesdZenithAngle=(udtSunCoordinatesdZenithAngle + dParallax)/rad;
	
	// AZIMUTH, ZENITH, ELEVATION
	return new Array(udtSunCoordinatesdAzimuth, udtSunCoordinatesdZenithAngle, 90-udtSunCoordinatesdZenithAngle);
}
