/** thangiswho.js
 * @author ThangisWho <www.thangiswho.com> 
 **/

/**
 / THIRD FUNCTION
 *
 * @return Array Return an array with page width, height and window width, height
 */
function getPageSize() {
	var xScroll, yScroll;
	if (window.innerHeight && window.scrollMaxY) {	
		xScroll = window.innerWidth + window.scrollMaxX;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	var windowWidth, windowHeight;
	if (self.innerHeight) {	// all except Explorer
		if(document.documentElement.clientWidth){
			windowWidth = document.documentElement.clientWidth; 
		} else {
			windowWidth = self.innerWidth;
		}
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}	
	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else { 
		pageHeight = yScroll;
	}
	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth){	
		pageWidth = xScroll;		
	} else {
		pageWidth = windowWidth;
	}
	return new Array(pageWidth,pageHeight,windowWidth,windowHeight);
};
/**
 / THIRD FUNCTION
 *
 * @return Array Return an array with x,y page scroll values.
 */
function getPageScroll() {
	var xScroll, yScroll;
	if (self.pageYOffset) {
		yScroll = self.pageYOffset;
		xScroll = self.pageXOffset;
	} else if (document.documentElement && document.documentElement.scrollTop) {	 // Explorer 6 Strict
		yScroll = document.documentElement.scrollTop;
		xScroll = document.documentElement.scrollLeft;
	} else if (document.body) {// all other Explorers
		yScroll = document.body.scrollTop;
		xScroll = document.body.scrollLeft;	
	}
	return new Array(xScroll,yScroll);
};

var $jQ = jQuery.noConflict();

//getMouseXY
var _mousex = 0, _mousey = 0;
function getMouseXY(e) {var cursor = {x:_mousex,y:_mousey}; e = e||window.event; if (! (e && e.clientX) ) return cursor; if (e.pageX || e.pageY) { cursor.x = e.pageX; cursor.y = e.pageY; } else { var de = document.documentElement; var b = document.body; cursor.x = e.clientX + (de.scrollLeft || b.scrollLeft) - (b.clientLeft || 0); cursor.y = e.clientY + (de.scrollTop || b.scrollTop) - (b.clientTop || 0); } return cursor;}
function setMouseXY(x,y) { _mousex = x; _mousey = y; }

function gotoLocation(url){
    window.location.href = url;
}
function gotoPosition(t){
	var my = $jQ(t).offset().top;
	_mousey = my;
	window.scrollTo(0, my );
}
function gotoHash(u,p,s) {
	var re = /https?:\/\/[^\/]+\.(vn|com)\//;
	if (u.match(re)) {
		u = u.replace(re, '/');
	}
	if (!s) s = '';
	if (p)
		self.document.location.hash = '#' + p+escape(u)+s;
	else
		self.document.location.hash = '#' + escape(u)+s;
}
function getHash(i) {
	if (!i) i = 1;
	var h = self.document.location.hash;
	if (!h) return '';
	if ( i > 0 )
		return h.substring(i) || '';
	else
		return h;
}
function showLoading(a,e) {
	$jQ('body').append('<div class="thAjaxLoading"><div class="loading"> </div></div>');
	a = a || false;
	if (a) {
		var c = getMouseXY(e);
		$jQ('.thAjaxLoading .loading').css({top:c.y-30, left:( (c.x > 700)? c.x-50 : c.x ) });
	}
}
function hideLoading() {
	var o = $jQ('.thAjaxLoading');
	if (o) o.remove();
}
function doGA(u) {
	if (_gaq) {
		u = u.replace(/([?&])(thAjax|noLeft)=[^&]+/g, '$1');
		u = u.replace(/[?&]$/, '');
		_gaq.push(['_trackPageview', u]);
		console.log("GA URL: "+u);
	}
}
function doPopup(o){
	if (!o.width) o.width=800;
	if (o.height == undefined) o.height=620;
	if (!o.params) o.params={};
	o.params.thAjax = 1;
	
	var d = $jQ('#dialogPopup');
	if (d) d.remove();
	$jQ('body').prepend('<div id="dialogPopup"></div>');
	d = $jQ('#dialogPopup');
	showLoading(true);
	
	$jQ.get(o.url, o.params, function(data) {
		d.html(data);
		var dlo = {
			title: o.title,
			resizable:false,
			draggable:false,
			modal: true,
			width: o.width,
			//height: o.height,
			buttons:{
				'Đóng lại': function(){ $jQ(this).dialog("destroy");}
			},
			close: function(e,ui) {$jQ(this).dialog( "destroy" );}
		};
		if (o.height > 0) dlo.height = o.height;
		d.dialog(dlo);
		if (o.complete) o.complete(d);
		hideLoading();
		doGA(o.url);
	});
}
function doThAjax(){
	var _u = getHash(1);
	if ( _u && _u.length > 2 && _u.substring(0,2) == "!/" ) {
		var t = [''];
		var idx = _u.indexOf('!', 2);
		if ( idx > 0 && idx < _u.length - 2 ) {
			t = _u.substring(idx+1).split('/');
			_u = _u.substring(1,idx);
		}
		else
			_u = _u.substring(1);
		
		_u = unescape(_u);
		_u = _u.replace(/([?&])(noLeft|thAjax)=[^&]*/, '$1');
		
		switch(t[0]) {
			case 'lb':
				var w = t[1] || 910;w = parseInt(w);
				var h = t[2] || 0;h = parseInt(h);
				var nc = t[3] ? false : true;
				thLightBox(_u, {thAjax:1, noLeft:1}, {width:w,height:h,noContainer:nc,autoHash:false});
				break;
			case 'pu':
				var w = t[1] || 930;w = parseInt(w);
				var h = t[2] || 0/*getPageSize()[3]-20*/;h = parseInt(h);
				var t = t[3] ? t[3] : '';
				doPopup({url:_u, params:{thAjax:1, noLeft:1}, width:w,height:h,title:t,
					complete: function(d) {
						var bs = d.find('.breadcrumbs');
						$jQ('#ui-dialog-title-'+d.attr('id') ).addClass('breadcrumbs').html ( bs.html() );
						bs.remove();
					}
				});
				break;
			case 'mn':
				var cu = 'http://www.2en.vn' + _u.replace(/\?.*$/,'');
				var co = false;
				$jQ('#main_menu li a').each(function(){
					var o = $jQ(this);
					if ( o.attr('href') == cu )
						co = o;
				})
				$jQ('#main_menu').find('.active').removeClass('active');
				if (co) co.parents('li').addClass('active');
				thAjax(_u, {thAjax:1}, {target:'#bodyContent',autoHash:false});
				break;
			default:
				thAjax(_u, {thAjax:1}, {target:'#bodyContent',autoHash:false});
				break;
		}
	}
}

function thAjaxComplete(u,options){
	doGA(u);
	
	if (options.hyperName) gotoPosition(options.target);//gotoHash(options.hyperName);
	if (options.autoHash) gotoHash(u, '!');
	hideLoading();
}
//thLightBox function
function thLightBox(u,p,o) {
	var options = $jQ.extend({
		width			:	910,
		height			:	0,
		title			:	'',
		noContainer		:	true,
		autoHash		:	false,
		imageLoading	:	'/images/lightbox/ico-loading.gif',
		imageBtnPrev	:	'/images/lightbox/btn-prev.gif',
		imageBtnNext	:	'/images/lightbox/btn-next.gif',
		imageBtnClose	:	'/images/lightbox/btn-close.gif',
		prefixURL		: ""
	},o);
	
	var _nolbstr = '<div id="jquery-overlay"></div><div id="jquery-lightbox" style="top:0px;left:0px;"><a href="#" id="lightbox-secNav-btnClose"><div class="windowClose"> </div></a><div id="lightboxContent"><div id="lightbox-loading"><img src="' + options.imageLoading + '"></div></div></div>';
	var _lbstr = '<div id="jquery-overlay"></div><div id="jquery-lightbox" style="top:0px;left:0px;"><div id="lightbox-container-image-data-box"><div id="lightbox-container-image-data"><div id="lightbox-image-details"><span id="lightbox-image-details-caption"></span></div><div id="lightbox-secNav"><a href="#" id="lightbox-secNav-btnClose"><img src="/images/lightbox/btn-close.gif"></a></div></div></div><div id="lightbox-container-image-box"><div id="lightbox-container-image"><div id="lightboxContent"><div id="lightbox-loading"><img src="' + options.imageLoading + '"></div></div></div></div></div>';
	
	_vbclose();
	_ghtml( options.prefixURL + u );

	function _ghtml(u) {
		$jQ('body').append( options.noContainer ? _nolbstr : _lbstr );
		var psize = getPageSize();
		var pscroll = getPageScroll();
		
		if ( options.width < 1 ) options.width = psize[2] - 200;
		if ( options.height < 1 ) options.height = psize[3] - 100;

		$jQ('#jquery-overlay').css({
			backgroundColor	:	'#000000',
			opacity			:	0.8,
			width			:	psize[0],
			height			:	psize[1]
		}).fadeIn();
		
		$jQ('#jquery-lightbox').css({
			top: pscroll[1] + 10,
			left:	pscroll[0] + ( psize[2] - options.width-20 ) /2,
			width: options.width+20
		}).show();
		
		$jQ('#lightbox-secNav-btnClose').bind('click', _vbclose);
		
		$jQ.get(u,p,function(data) {
			_lbox(data,options.title);
			thAjaxComplete(u,options);
		});
	}
	
	function _lbox(c,t) {
		if ( ! options.noContainer ) {
			$jQ('#lightbox-image-details-caption').html(t);
			$jQ('#lightbox-container-image-data-box').css({width: options.width});
			$jQ('#lightbox-container-image-box').css({width: options.width+20, height: options.height+20});
		}
		
		$jQ('#lightboxContent').html(c);
	}
	function _vbclose() {
		var jo = $jQ('#jquery-overlay');
		if (jo) { 
			$jQ('#jquery-lightbox').remove();
			jo.remove();//jo.fadeOut(function() { jo.remove(); });
		}
		return false;
	}
};
//thAjax
function thAjax(u,p,options) {
	var options = $jQ.extend({
		hyperName	: false,
		autoHash	: false,
		autoCursor	: true,
		target		: false,
		dataType	: "html",
		type		: "get",
		cache		: true,
		beforeSend	: false,
		complete	: false,
		success		: false,
		error		: false
	}, options);
	
	$jQ.ajax({
		type		: options.type,
		url			: u,
		data		: p,
		dataType 	: options.dataType,
		cache		: options.cache,
		async		: true,
		timeout		: 20000,
		beforeSend	: function(){
			showLoading(options.autoCursor);
			if(options.beforeSend) options.beforeSend();
		},
		complete	: function(XMLHttpReq, textStatus){
			thAjaxComplete(u,options);
			if(options.complete) options.complete(XMLHttpReq, textStatus);
		},
		success		: function(data){
			if (options.target)
				$jQ(options.target).html(data);
			if(options.success) options.success(data);
		},
		error		: function (event, request, thrownError){
			if (options.error) options.error(event, request, settings);
			//alert('error');
		}
	});
}//ends thAjax

(function ($) {
	
	$.fn.thToggle = function (options) {
		var options = $.extend( {
			isWindow		: true,
			event			: "click",
			target			: "#content"
		}, options);
		
		this.each(function () {
			$(options.target).addClass('window');
			if ( options.isWindow ) {
				$(options.target).html('<div class="windowClose"><img src="/images/window-close.gif"/></div>' +
					'<div class="windowData">' + $(options.target).html() + 
					'</div>' );
				$(options.target + ' .windowClose').click( function() { $(options.target).hide('slow'); } );
			}
			$(this).bind(options.event, function(){
				$(options.target).toggle('fast');
				return false;
			});
		});
		
		return this;
	}; // ends thToggle
	$.fn.thAjaxForm = function (options) {
		var options = $.extend( {
			disabledClass: "disabled",
			disabledAttr: "disabled",
			disabledAttrValue: "disabled",
			buttonDesign:true,
			redirectURL: false,
			onSuccess: false,
			disabledOnOK: true,
			afterSubmit: false,
			dataType		: "html",
			imageLoading	:	'/images/lightbox/ico-loading.gif'
		}, options);
		
		this.each(function () {
			var subm = $('input:submit',this);
			var mes = $('#message', this);
			
			if ( subm.attr(options.disabledAttr) )
				subm.removeAttr(options.disabledAttr);
			if (options.buttonDesign)
				subm.button();
			else {
				//subm.addClass('ui-button ui-widget ui-corner-all ui-state-hover');
			}
			
			$(this).ajaxForm({
				dataType: options.dataType,
				beforeSubmit: function(){
					subm.attr(options.disabledAttr,options.disabledAttrValue).addClass(options.disabledClass);
					mes.html('<image src="'+options.imageLoading+'"/>');
				},
				success: function(data, statusText, xhr, $form ) {
					subm.removeAttr(options.disabledAttr).removeClass(options.disabledClass);
					if ( statusText == 'success' ) {
						if ( data == 'ok' ) {
							if ( options.disabledOnOK )
								subm.attr(options.disabledAttr,options.disabledAttrValue).addClass(options.disabledClass);
							
							if (options.redirectURL) {
								self.location = options.redirectURL;
								return;
							}
							else if (options.onSuccess) {
								options.onSuccess();
							}
							else
								mes.html('<span class="ui-icon ui-icon-check" style="float:left;"> </span><b>Đã thành công</b>');
						}
						else {
							mes.html('<span class="ui-icon ui-icon-alert" style="float:left;"> </span> '+ data);
							if (options.afterSubmit)
								options.afterSubmit(data);
						}
					}
					else
						mes.html('<span class="ui-icon ui-icon-alert"> </span>Lỗi xảy ra! Xin bạn thử lại lần sau.');
				},
				error: function (event, request, settings){ 
					subm.removeAttr(options.disabledAttr).removeClass(options.disabledClass);
					mes.html('<span class="ui-icon ui-icon-closethick"> </span>Lỗi xảy ra! Xin bạn thử lại lần sau.'); 
				}
			});
		});
		
		return this;
	}; // ends thAjaxForm
	
	//thSlide function
	$.fn.thSlide= function(options) {
		var options = $.extend({
			slideSelector: '.slides',
			slideWidth		: 300,
			slideHeight		: 0,
			thumbSelector: '.thumbs',
			thumbItemSelector: 'li',
			slideItemClass: 'slideItem',
			thumbItemClass: 'thumbItem',
			time: 300,
			auto: false,
			autoSecond: 3
		}, options);
		
		this.each(function () {
			var $o = $(this);
			var $so = $o.find(options.slideSelector);
			var $to = $o.find(options.thumbSelector);
			
			var sw=0;
			var positions = new Array();
			$so.find( 'img' ).each(function(i){
				positions[i]= sw;
				var iw = (options.slideHeight > 0) ? options.slideHeight : options.slideWidth;//parseInt ( $(this).attr('width') );
				sw += iw;
			});
			if (options.slideHeight > 0)
				$so.height(sw);
			else
				$so.width(sw);

			/* On a thumbnail click */
			$to.find(options.thumbItemSelector + '.' + options.thumbItemClass + ' a').click(function(e){
				var ao = $(this);
				$( options.thumbItemSelector + '.' + options.thumbItemClass ).removeClass('active').addClass('inactive');
				ao.parent().addClass('active');
				
				var pos = ao.parent().prevAll('.' + options.thumbItemClass).length;
				
				if (options.slideHeight > 0)
					$so.stop().animate({marginTop:-positions[pos]+'px'}, options.time );
				else
					$so.stop().animate({marginLeft:-positions[pos]+'px'}, options.time );
				
				e.preventDefault();
				return false;
			});
	
			$to.find(options.thumbItemSelector + '.' + options.thumbItemClass + ':first').addClass('active').siblings().addClass('inactive');

			/* auto slide */
			if ( options.auto ) {
				var current = 1;
				var toa = $to.find(options.thumbItemSelector + '.' + options.thumbItemClass + ' a');
				setInterval( function(){
					toa.eq( current % toa.length).trigger('click',[true]);
					current++;
				}, options.autoSecond * 1000);
			}
		});
		
		return this;
	};//end thSlide
	
	//thZoom
	$.fn.thZoom = function(options){
        options = $.extend({
			'diameter':200,
			'borderColor':'#ccc',
			'borderWidth':'1px',
			'borderStyle':'solid',
			marginLeft: 100,
			marginTop: 0,
			time: 300
		}, options);

		this.each(function() {
			var $o = $(this);
			var loupe = $o;
			var wrpImage; 
			var lWidth; 
			var lHeight; 
			var sWidth; 
			var sHeight;
			
			var oimage = new Image();
			oimage.src = $o.attr('fullsrc');
			
			$o.bind({
				mouseenter: function(e) {
					$o.css('cursor','crosshair'); 
					sWidth = $o.width(); 
					sHeight = $o.height(); 

					var lImage = oimage;
					lWidth = lImage.width;
					lHeight = lImage.height;
					
					loupe = $('<div>').css({
						position: 'absolute',
						width: options.diameter,
						height: options.diameter,
						'border-width': options.borderWidth,
						'border-style':  options.borderStyle,
						'border-color': options.borderColor,
						overflow: 'hidden',
						'z-index': '2000',
						/*
						'-moz-border-radius': options.diameter/2,
						'-khtml-border-radius': options.diameter/2,
						'border-radius': options.diameter/2,
						*/
						background: 'url('+lImage.src+') no-repeat'
					}).attr('id','iLoupe');				
						
					$('body').append(loupe);
				},
				mousemove: function(e) {
					var sxPointer = e.pageX - $o.offset().left - parseInt($o.css('padding-left'));
					var syPointer = e.pageY - $o.offset().top - parseInt($o.css('padding-top'));
					
					loupe.css({
						left: e.pageX + options.marginLeft,
						top: e.pageY + options.marginTop
					});
					
					var sxPointerPer = sxPointer/sWidth*100;
					var syPointerPer = syPointer/sHeight*100;
					sxPointerPer = Math.round(sxPointerPer*Math.pow(10,10))/Math.pow(10,10);
					syPointerPer = Math.round(syPointerPer*Math.pow(10,10))/Math.pow(10,10);
					
					var sXPointer = Math.round(((sxPointerPer/100*lWidth)*Math.pow(10,0))/Math.pow(10,0));
					var sYPointer = Math.round(((syPointerPer/100*lHeight)*Math.pow(10,0))/Math.pow(10,0));
					
					(sxPointer>=0 && sxPointer<=sWidth && syPointer>=0 && syPointer<=sHeight) ? loupe.css({"background-position":(-sXPointer+options.diameter/2)+"px "+(-sYPointer+options.diameter/2)+"px"}) : false;
				},
				mouseleave: function() {
					loupe.stop(true, true).fadeOut(options.time, function() {
						loupe.remove();
					});
				}             
			});
		});
		
        return this;
	};//ends thZoom
	
	//thGetAjax
	$.fn.thGetAjax = function(options) {
		var options = $.extend({
			target		:	'body',
			autoCursor	:	false,
			autoHash	:	true,
			hyperName	:	false,
			url			:	false,
			type		:	"get",
			success		:	false,
			params		:	{}
		},options);
		options.params.thAjax = 1;
		
		this.each(function() {
			var o = $(this);
			if (o.hasClass('noAjax') )
				return;
			
			if (options.url)
				_ghtml(options.url);
			else {
				var u = o.attr('href');
				o.click(function(e){
					e.preventDefault();
					_ghtml(u);
					return false;
				});
			}
		});
		
		function _ghtml(u) {
			thAjax(u,options.params,options);
		}
		
		return this;
	}; //ends thGetAjax
	
	//thLightBox function
	$.fn.thLightBox = function(options) {
		var options = $.extend({
			width			:	0,
			height			:	0,
			url				:	false,
			noContainer		:	false,
			autoHash		:	true,
			imageLoading	:	'/images/lightbox/ico-loading.gif',
			imageBtnPrev	:	'/images/lightbox/btn-prev.gif',
			imageBtnNext	:	'/images/lightbox/btn-next.gif',
			imageBtnClose	:	'/images/lightbox/btn-close.gif',
			prefixURL		: "",
			params			: {}
		},options);
		
		var _nolbstr = '<div id="jquery-overlay"></div><div id="jquery-lightbox" style="top:0px;left:0px;"><a href="#" id="lightbox-secNav-btnClose"><div class="windowClose"> </div></a><div id="lightboxContent"><div id="lightbox-loading"><img src="' + options.imageLoading + '"></div></div></div>';
		var _lbstr = '<div id="jquery-overlay"></div><div id="jquery-lightbox" style="top:0px;left:0px;"><div id="lightbox-container-image-data-box"><div id="lightbox-container-image-data"><div id="lightbox-image-details"><span id="lightbox-image-details-caption"></span></div><div id="lightbox-secNav"><a href="#" id="lightbox-secNav-btnClose"><img src="/images/lightbox/btn-close.gif"></a></div></div></div><div id="lightbox-container-image-box"><div id="lightbox-container-image"><div id="lightboxContent"><div id="lightbox-loading"><img src="' + options.imageLoading + '"></div></div></div></div></div>';
			
		this.each(function () {
			var o = $(this);
			if (o.hasClass('noLightBox') )
				return;
			
			var t = o.attr('title'); if (!t) t = '';
			var w = options.width
			var h = options.height;
			
			if (o.attr('thWidth') )
				w = o.attr('thWidth');
			if (o.attr('thHeight') )
				h = o.attr('thHeight');
				
			if (options.url)
				_ghtml( options.prefixURL + options.url, t,w,h );
			else {
				var u = o.attr('href');
				o.click(function(e){
					e.preventDefault();
					_ghtml( options.prefixURL + u, t,w,h );
					return false;
				});
			}
		});

		function _ghtml(u,t,w,h) {
			$('body').append( options.noContainer ? _nolbstr : _lbstr );
			var psize = getPageSize();
			var pscroll = getPageScroll();
			
			if ( w < 1 ) w = psize[2] - 200;
			if ( h < 1 ) h = psize[3] - 100;
			
			$('#jquery-overlay').css({
				opacity			:	0.8,
				width			:	psize[0],
				height			:	psize[1]
			}).fadeIn();
			
			$('#jquery-lightbox').css({
				top: pscroll[1] + 10,
				left:	pscroll[0] + ( psize[2] - w-20 ) /2,
				width: w+20
			}).show();
			
			$('#lightbox-secNav-btnClose').bind('click', _vbclose);
			
			$.get(u,options.params,function(data) {
				_lbox(data,t,w,h);
				thAjaxComplete(u,options);
			});
		}
		
		function _lbox(c,t,w,h) {
			if ( ! options.noContainer ) {
				$('#lightbox-image-details-caption').html(t);
				$('#lightbox-container-image-data-box').css({width: w});
				$('#lightbox-container-image-box').css({width: w+20, height: h+20});
			}
			
			$('#lightboxContent').html(c);
		}
		function _vbclose() {
			var jo = $('#jquery-overlay');
			if (jo) { 
				$('#jquery-lightbox').remove();
				jo.remove();//jo.fadeOut(function() { jo.remove(); });
			}
			return false;
		}
		
		return this;
	};
	//end thLightBox
})(jQuery);

// public functions
var PI = Math.PI;

/* Discard the fractional part of a number, e.g., INT(3.2) = 3 */
function INT(d) {
	return Math.floor(d);
}

/* Compute the (integral) Julian day number of day dd/mm/yyyy, i.e., the number 
 * of days between 1/1/4713 BC (Julian calendar) and dd/mm/yyyy. 
 * Formula from http://www.tondering.dk/claus/calendar.html
 */
function jdFromDate(dd, mm, yy) {
	var a, y, m, jd;
	a = INT((14 - mm) / 12);
	y = yy+4800-a;
	m = mm+12*a-3;
	jd = dd + INT((153*m+2)/5) + 365*y + INT(y/4) - INT(y/100) + INT(y/400) - 32045;
	if (jd < 2299161) {
		jd = dd + INT((153*m+2)/5) + 365*y + INT(y/4) - 32083;
	}
	return jd;
}

/* Convert a Julian day number to day/month/year. Parameter jd is an integer */
function jdToDate(jd) {
	var a, b, c, d, e, m, day, month, year;
	if (jd > 2299160) { // After 5/10/1582, Gregorian calendar
		a = jd + 32044;
		b = INT((4*a+3)/146097);
		c = a - INT((b*146097)/4);
	} else {
		b = 0;
		c = jd + 32082;
	}
	d = INT((4*c+3)/1461);
	e = c - INT((1461*d)/4);
	m = INT((5*e+2)/153);
	day = e - INT((153*m+2)/5) + 1;
	month = m + 3 - 12*INT(m/10);
	year = b*100 + d - 4800 + INT(m/10);
	return new Array(day, month, year);
}

/* Compute the time of the k-th new moon after the new moon of 1/1/1900 13:52 UCT 
 * (measured as the number of days since 1/1/4713 BC noon UCT, e.g., 2451545.125 is 1/1/2000 15:00 UTC).
 * Returns a floating number, e.g., 2415079.9758617813 for k=2 or 2414961.935157746 for k=-2
 * Algorithm from: "Astronomical Algorithms" by Jean Meeus, 1998
 */
function NewMoon(k) {
	var T, T2, T3, dr, Jd1, M, Mpr, F, C1, deltat, JdNew;
	T = k/1236.85; // Time in Julian centuries from 1900 January 0.5
	T2 = T * T;
	T3 = T2 * T;
	dr = PI/180;
	Jd1 = 2415020.75933 + 29.53058868*k + 0.0001178*T2 - 0.000000155*T3;
	Jd1 = Jd1 + 0.00033*Math.sin((166.56 + 132.87*T - 0.009173*T2)*dr); // Mean new moon
	M = 359.2242 + 29.10535608*k - 0.0000333*T2 - 0.00000347*T3; // Sun's mean anomaly
	Mpr = 306.0253 + 385.81691806*k + 0.0107306*T2 + 0.00001236*T3; // Moon's mean anomaly
	F = 21.2964 + 390.67050646*k - 0.0016528*T2 - 0.00000239*T3; // Moon's argument of latitude
	C1=(0.1734 - 0.000393*T)*Math.sin(M*dr) + 0.0021*Math.sin(2*dr*M);
	C1 = C1 - 0.4068*Math.sin(Mpr*dr) + 0.0161*Math.sin(dr*2*Mpr);
	C1 = C1 - 0.0004*Math.sin(dr*3*Mpr);
	C1 = C1 + 0.0104*Math.sin(dr*2*F) - 0.0051*Math.sin(dr*(M+Mpr));
	C1 = C1 - 0.0074*Math.sin(dr*(M-Mpr)) + 0.0004*Math.sin(dr*(2*F+M));
	C1 = C1 - 0.0004*Math.sin(dr*(2*F-M)) - 0.0006*Math.sin(dr*(2*F+Mpr));
	C1 = C1 + 0.0010*Math.sin(dr*(2*F-Mpr)) + 0.0005*Math.sin(dr*(2*Mpr+M));
	if (T < -11) {
		deltat= 0.001 + 0.000839*T + 0.0002261*T2 - 0.00000845*T3 - 0.000000081*T*T3;
	} else {
		deltat= -0.000278 + 0.000265*T + 0.000262*T2;
	};
	JdNew = Jd1 + C1 - deltat;
	return JdNew;
}

/* Compute the longitude of the sun at any time. 
 * Parameter: floating number jdn, the number of days since 1/1/4713 BC noon
 * Algorithm from: "Astronomical Algorithms" by Jean Meeus, 1998
 */
function SunLongitude(jdn) {
	var T, T2, dr, M, L0, DL, L;
	T = (jdn - 2451545.0 ) / 36525; // Time in Julian centuries from 2000-01-01 12:00:00 GMT
	T2 = T*T;
	dr = PI/180; // degree to radian
	M = 357.52910 + 35999.05030*T - 0.0001559*T2 - 0.00000048*T*T2; // mean anomaly, degree
	L0 = 280.46645 + 36000.76983*T + 0.0003032*T2; // mean longitude, degree
	DL = (1.914600 - 0.004817*T - 0.000014*T2)*Math.sin(dr*M);
	DL = DL + (0.019993 - 0.000101*T)*Math.sin(dr*2*M) + 0.000290*Math.sin(dr*3*M);
	L = L0 + DL; // true longitude, degree
	L = L*dr;
	L = L - PI*2*(INT(L/(PI*2))); // Normalize to (0, 2*PI)
	return L;
}

/* Compute sun position at midnight of the day with the given Julian day number. 
 * The time zone if the time difference between local time and UTC: 7.0 for UTC+7:00.
 * The function returns a number between 0 and 11. 
 * From the day after March equinox and the 1st major term after March equinox, 0 is returned. 
 * After that, return 1, 2, 3 ... 
 */
function getSunLongitude(dayNumber, timeZone) {
	return INT(SunLongitude(dayNumber - 0.5 - timeZone/24)/PI*6);
}

/* Compute the day of the k-th new moon in the given time zone.
 * The time zone if the time difference between local time and UTC: 7.0 for UTC+7:00
 */
function getNewMoonDay(k, timeZone) {
	return INT(NewMoon(k) + 0.5 + timeZone/24);
}

/* Find the day that starts the luner month 11 of the given year for the given time zone */
function getLunarMonth11(yy, timeZone) {
	var k, off, nm, sunLong;
	//off = jdFromDate(31, 12, yy) - 2415021.076998695;
	off = jdFromDate(31, 12, yy) - 2415021;
	k = INT(off / 29.530588853);
	nm = getNewMoonDay(k, timeZone);
	sunLong = getSunLongitude(nm, timeZone); // sun longitude at local midnight
	if (sunLong >= 9) {
		nm = getNewMoonDay(k-1, timeZone);
	}
	return nm;
}

/* Find the index of the leap month after the month starting on the day a11. */
function getLeapMonthOffset(a11, timeZone) {
	var k, last, arc, i;
	k = INT((a11 - 2415021.076998695) / 29.530588853 + 0.5);
	last = 0;
	i = 1; // We start with the month following lunar month 11
	arc = getSunLongitude(getNewMoonDay(k+i, timeZone), timeZone);
	do {
		last = arc;
		i++;
		arc = getSunLongitude(getNewMoonDay(k+i, timeZone), timeZone);
	} while (arc != last && i < 14);
	return i-1;
}

/* Comvert solar date dd/mm/yyyy to the corresponding lunar date */
function convertSolar2Lunar(dd, mm, yy, timeZone) {
	var k, dayNumber, monthStart, a11, b11, lunarDay, lunarMonth, lunarYear, lunarLeap;
	dayNumber = jdFromDate(dd, mm, yy);
	k = INT((dayNumber - 2415021.076998695) / 29.530588853);
	monthStart = getNewMoonDay(k+1, timeZone);
	if (monthStart > dayNumber) {
		monthStart = getNewMoonDay(k, timeZone);
	}
	//alert(dayNumber+" -> "+monthStart);
	a11 = getLunarMonth11(yy, timeZone);
	b11 = a11;
	if (a11 >= monthStart) {
		lunarYear = yy;
		a11 = getLunarMonth11(yy-1, timeZone);
	} else {
		lunarYear = yy+1;
		b11 = getLunarMonth11(yy+1, timeZone);
	}
	lunarDay = dayNumber-monthStart+1;
	diff = INT((monthStart - a11)/29);
	lunarLeap = 0;
	lunarMonth = diff+11;
	if (b11 - a11 > 365) {
		leapMonthDiff = getLeapMonthOffset(a11, timeZone);
		if (diff >= leapMonthDiff) {
			lunarMonth = diff + 10;
			if (diff == leapMonthDiff) {
				lunarLeap = 1;
			}
		}
	}
	if (lunarMonth > 12) {
		lunarMonth = lunarMonth - 12;
	}
	if (lunarMonth >= 11 && diff < 4) {
		lunarYear -= 1;
	}
	return new Array(lunarDay, lunarMonth, lunarYear, lunarLeap);
}

/* Convert a lunar date to the corresponding solar date */
function convertLunar2Solar(lunarDay, lunarMonth, lunarYear, lunarLeap, timeZone) {
	var k, a11, b11, off, leapOff, leapMonth, monthStart;
	if (lunarMonth < 11) {
		a11 = getLunarMonth11(lunarYear-1, timeZone);
		b11 = getLunarMonth11(lunarYear, timeZone);
	} else {
		a11 = getLunarMonth11(lunarYear, timeZone);
		b11 = getLunarMonth11(lunarYear+1, timeZone);
	}
	k = INT(0.5 + (a11 - 2415021.076998695) / 29.530588853);
	off = lunarMonth - 11;
	if (off < 0) {
		off += 12;
	}
	if (b11 - a11 > 365) {
		leapOff = getLeapMonthOffset(a11, timeZone);
		leapMonth = leapOff - 2;
		if (leapMonth < 0) {
			leapMonth += 12;
		}
		if (lunarLeap != 0 && lunarMonth != leapMonth) {
			return new Array(0, 0, 0);
		} else if (lunarLeap != 0 || off >= leapOff) {
			off += 1;
		}
	}
	monthStart = getNewMoonDay(k+off, timeZone);
	return jdToDate(monthStart+lunarDay-1);
}

var dayNamesMin_vi_VN = ['CN','T2','T3','T4','T5','T6','T7'];
var dayNames_vi_VN = ['Chủ Nhật','Thứ Hai','Thứ Ba','Thứ Tư','Thứ Năm','Thứ Sáu','Thứ Bảy'];
var monthNames_vi_VN = ['Tháng 1','Tháng 2','Tháng 3','Tháng 4','Tháng 5','Tháng 6','Tháng 7','Tháng 8','Tháng 9','Tháng 10','Tháng 11','Tháng 12'];
function thangiswho_today(m,d) {
	var t = new Date();
	var ret = '<div class="day">' + t.getDate() + '</div><div class="date">' + d[t.getDay()] + '</div>';
	var lu = convertSolar2Lunar(t.getDate(),t.getMonth()+1, t.getFullYear(), 7);
	ret += '<div class="lunar">Âm lịch: ' + lu[0] +' '+ m[lu[1]-1] +', '+ lu[2] +'</div>';
	
	return ret;
}
function thangiswho_jdhtml(d) {
	var ret = d.getDate() + '<div class="ui-datepicker-lunar">';
	var lu = convertSolar2Lunar(d.getDate(),d.getMonth()+1, d.getFullYear(), 7);
	if ( lu[0] == 1 || lu[0] == 15 )
		ret += lu[0] + '/' + lu[1];
	else
		ret += lu[0];
	ret += '</div>';
	return ret;
}

