"use strict";

function ClickTooltipTime(nUnixtimeSeconds, mxParentPositionReference, strDisplayMode)
{
	var _self=this;

	var bIsValid = (typeof mxParentPositionReference=="string")?document.getElementById(mxParentPositionReference):mxParentPositionReference;
	if (!bIsValid)
	{
		throw new Error("ClickTooltipTime mxParentPositionReference is not yet a descendant of document.body or is invalid.");
	}
	
	this.objDate=new Date(nUnixtimeSeconds*1000);
	this.strDisplayMode = strDisplayMode || ClickTooltipTime.displayRelative;
	var bAutoUpdate = (strDisplayMode == ClickTooltipTime.displayRelative);
	this.timeAgo=new TimeAgo(ClickTooltipTime.strTimeAgoClassName, null, null, null, null, bAutoUpdate);
	
	ClickTooltip.call(
		this,
		this.getDefaultHTML(),
		mxParentPositionReference
	);

	this.invalidate();
}

ClickTooltipTime.prototype=new ClickTooltip();
ClickTooltipTime.prototype.constructor=ClickTooltipTime;


(function(objExtend){
	for(var strProperty in objExtend)
		ClickTooltipTime.prototype[strProperty]=objExtend[strProperty];
})({
	/**
	* Date object of nUnixtimeSeconds.
	*/
	objDate: null,
	
	
	/**
	* TimeAgo instance especially configured for ClickTooltipTime.
	*/
	timeAgo: null,
	
	
	/**
	* If non-null, it is the setIntervalID for refreshing tooltip HTML.
	* Should be non-null only when isVisible() is true.
	*/
	nIntervalID: null,


	/**
	* Which date format should be displayed when tooltip not open
	*/
	strDisplayMode: null,
	
	

	show: function()
	{
		if(this.nIntervalID===null)
		{
			var _self=this;
			this.nIntervalID=setInterval(function(){
				_self.invalidate();
			}, 500);
		}
		
		this.invalidate();
		ClickTooltip.prototype.show.call(this);
	},


	hide: function()
	{
		if(this.nIntervalID!==null)
		{
			clearInterval(this.nIntervalID);
			this.nIntervalID=null;
		}
		
		ClickTooltip.prototype.hide.call(this);
	},


	invalidate: function()
	{
		this.setHTML(this.getDefaultHTML());


		var nCurrentTimeSeconds=parseInt(new Date().getTime()/1000)+TimeAgo.nSecondsAdjust;
		var nUnixtimeSeconds=parseInt(this._elParentPositionReference.getAttribute("data-unixtime-seconds"));

		if(this.strDisplayMode === ClickTooltipTime.displayLocal) {
			this._elParentPositionReference.innerHTML=ClickTooltipTime.localTimeString(this.objDate);
		}
		else if(this.strDisplayMode === ClickTooltipTime.displayUTC) {
			this._elParentPositionReference.innerHTML=ClickTooltipTime.UTCTimeString(this.objDate);
		}
		else {
			this._elParentPositionReference.innerHTML=this.timeAgo.relativeTime(nUnixtimeSeconds, nCurrentTimeSeconds);
		}
	},


	getDefaultHTML: function()
	{
		return [
			this.timeAgo.relativeTime(parseInt(this.objDate.getTime()/1000), null, /*nMaximumUnitTypes*/ 3),
			ClickTooltipTime.UTCTimeString(this.objDate),
			ClickTooltipTime.localTimeString(this.objDate)
		].join("<br>");
	}
});


/**
* CSS class name for TooltipTime TimeAgo tags. 
*/
ClickTooltipTime.strTimeAgoClassName="ClickTooltipTime_TimeAgo";


/**
 * Returns a timestamp in this format:
 * 2013-01-02 15:13:14 local time (+03:00).
 * See ClickTooltipTime.strLabelLocalTime.
 *
 * @return {string}
*/
ClickTooltipTime.localTimeString=function(objDate)
{
	function pad(nNumber){
		return ("0"+nNumber.toString()).substr(-2);
	}
	
	var strTimezoneSign=parseInt(objDate.getTimezoneOffset()/60*-1)>=0?"+":"-";
	
	return objDate.getFullYear()
		+ "<span class='datepart' style='white-space: nowrap'>"
		+ "-" + pad( objDate.getMonth() + 1 )
		+ "-" + pad( objDate.getDate() )
		+ " " + pad( objDate.getHours() )
		+ "</span>"
		+ "<span class='timepart' style='white-space: nowrap'>"
		+ ":" + pad( objDate.getMinutes() )
		+ ":" + pad( objDate.getSeconds() )
		+ " " + ClickTooltipTime.strLabelLocalTime
		+ " (" + strTimezoneSign + pad(parseInt(Math.abs(objDate.getTimezoneOffset()/60)))+":"+pad(parseInt(Math.abs(objDate.getTimezoneOffset())%60)) + ")"
		+ "</span>"
	;
};


/**
 * Returns a timestamp in this format:
 * 2013-01-02 12:13:14 UTC.
 *
 * @return {string}
 */
ClickTooltipTime.UTCTimeString=function(objDate)
{
	function pad(nNumber){
		return ("0"+nNumber.toString()).substr(-2);
	}
	
	return objDate.getUTCFullYear()
		+ "<span class='datepart' style='white-space: nowrap'>"
		+ "-" + pad( objDate.getUTCMonth() + 1 )
		+ "-" + pad( objDate.getUTCDate() )
		+ "</span>"
		+ "<span class='timepart' style='white-space: nowrap'>"
		+ " " + pad( objDate.getUTCHours() )
		+ ":" + pad( objDate.getUTCMinutes() )
		+ ":" + pad( objDate.getUTCSeconds() )
		+ " UTC"
		+ "</span>"
	;
};


/**
* A text used like this:
* 2013-01-02 12:13:14 local time (+03:00).
*/
ClickTooltipTime.strLabelLocalTime="local time";

ClickTooltipTime.displayRelative = "relative";
ClickTooltipTime.displayUTC = "utc";
ClickTooltipTime.displayLocal = "local";


/**
* Utility function.
*/
ClickTooltipTime.onLoadWindow=function(nUnixtimeSeconds, mxParentPositionReference, strDisplayMode){
	window.addEventListener("load", function(){
		new ClickTooltipTime(
			nUnixtimeSeconds,
			mxParentPositionReference,
			strDisplayMode
		);
	});
};