Number.prototype.toInt = function(base)
{
	return parseInt(this, base || 10);
};

/*
Class:
	TimePicker
	The time picker class will add a time picker
	where the user can drag on the handls of a clock

Options:

	startTime:
		The initial time (as an object) for the time picker (hour between 0 to 23, minute between 0 to 59)

	selectedTime:
		The initial seelcted time (as an object) for the time picker (hour between 0 to 23, minute between 0 to 59)

	format24:
		Use a 24 hours format if true

	imagesPath:
		The path to the images folder that hold the time picker images (without a trailing slash).

	faceImage:
		The clock face image.

	hourHandImage:
		The hour hand image (one image for 12 hours using CSS spirits).

	minuteHandImage:
		The minute hand image (one image for 60 minutes using CSS spirits).

	centerImage:
		The center image for the clock (the hands nob).

	clockSize:
		Because there could be a delay in loading the images, the clockSize is the image faceImage size.

	hourHandSize:
		The width and height of the hourHangImage to show one hour (the total width divided by 12). Give or take 1 pixel.

	minuteHandSize:
		The width and height of the minuteHangImage to show one minute (the total width divided by 60). Give or take 1 pixel.

	centerSize:
		The width and height of the centerImage.

	ampmStyles:
		The CSS style object for the AM/PM link.

	lang:
		The language variables for AM/PM. Also used for user input.


Events:

	onChange:
		Event that will be fired when the time is changed.


Variables:
	this.time:
		the current time (either initial or selected)


Function:
	updateAmPm:
		update the text link HTML value from am to pm or the opposite

	moveHands:
		move the clock hands based on the time selected

	clickAngle:
		return the angle from the user click

*/

function TimePicker(holder, options)
{
	this.options = {
		startTime:
		{
			hour:new Date().getHours(),
			minute: new Date().getMinutes()
		},

		selectedTime: null,

		format24: false,

		imagesPath: "maps/js/tp/time_picker_files/images",
		faceImage: "clock_face.gif",
		hourHandImage: "clock_hours.gif",
		minuteHandImage: "clock_minutes.gif",
		centerImage: "clock_center.gif",

		clockSize:
		{
			width:142,
			height:142
		},

		hourHandSize:
		{
			width:67,
			height:68
		},

		minuteHandSize:
		{
			width:111,
			height:112
		},

		centerSize:
		{
			width:7,
			height:6
		},

		ampmStyles:
		{
			fontSize:'10pt',
			fontWeight:'bold',
			color:'#999999',
			textDecoration:'none'
		},

		lang:
		{
			am:'AM',
			pm:'PM'
		}
	};

	this.onChange = function(tp)
	{
		return;
	};
	
	this.updateAmPm = function()
	{
		if (this.time.hour < 12)
			this.ampm.text(this.options.lang.am);
		else
			this.ampm.text(this.options.lang.pm);
	};
	
	this.moveHands = function()
	{
		try
		{
			this.hourHand.css("background-position", (((this.time.hour % 12) *  this.options.hourHandSize.width) * -1));
			this.minuteHand.css("background-position", ((this.time.minute * this.options.minuteHandSize.width) * -1));
		}
		catch(e){}
	};
	
	this.clickAngle = function(pnt, coord)
	{
		var c_x = coord.width / 2;
		var c_y = coord.height / 2;
		
		var x = pnt.x + jQuery(window).scrollLeft() - coord.left;
		var y = pnt.y + jQuery(window).scrollTop() - coord.top;
		
		var t_x = c_x;
		var t_y = y;
		
		var CA = t_x - x;
		var CO = t_y - c_y;
		var AO = Math.sqrt(Math.pow(CA, 2) + Math.pow(CO, 2));
		
		var ang = Math.round((Math.acos((Math.pow(Math.abs(CA), 2) - Math.pow(Math.abs(AO), 2) - Math.pow(CO, 2))/(2 * CO * AO))) * 180/Math.PI);
		
		if (x < c_x) ang = 360 - ang;
		
		return ang;
	};

	this.holder = jQuery("#" + holder);

	if (options.onChange != undefined)
	{
		this.onChange = options.onChange;
		delete options.onChange;
	}

	for (var key in options)
		this.options[key] = options[key];

	this.moveEl = {};
	this.moveEl['move'] = false;

	if (this.options.selectedTime != undefined) this.time = this.options.selectedTime;
	else this.time = this.options.startTime;

	this.holder.css({width:this.options.clockSize.width, height:this.options.clockSize.height});

	var img = jQuery("<img src=\"" + this.options.imagesPath + "/" + this.options.faceImage + "\" style=\"position: absolute; z-index: 21000;\" />");

	this.holder.append(img);
	
	this.minuteHand = jQuery("<div style=\"margin-top: " + ((this.options.clockSize.height - this.options.minuteHandSize.height) / 2).toInt() + "px; margin-left: " + ((this.options.clockSize.width - this.options.minuteHandSize.width) / 2).toInt() + "px; width: " + this.options.minuteHandSize.width + "px; height: " + this.options.minuteHandSize.height + "px; position: absolute; z-index: 22000; background: url(" + this.options.imagesPath + "/" + this.options.minuteHandImage + ") no-repeat top left;\" >");
												
	this.holder.append(this.minuteHand);


	this.hourHand = jQuery("<div style=\"margin-top: " + ((this.options.clockSize.height - this.options.hourHandSize.height) / 2).toInt() + "px; margin-left: " + ((this.options.clockSize.width - this.options.hourHandSize.width) / 2).toInt() + "px; width: " + this.options.hourHandSize.width + "px; height: " + this.options.hourHandSize.height + "px; position: absolute; z-index: 23000; background: url(" + this.options.imagesPath + "/" + this.options.hourHandImage + ") no-repeat top left;\" />");
												
	this.holder.append(this.hourHand);
	
	var c_img = jQuery("<img src=\"" + this.options.imagesPath + "/" + this.options.centerImage + "\" style=\"position: absolute; z-index: 24000; margin-top: " + ((this.options.clockSize.height - this.options.centerSize.height)/2).toInt() + "px; margin-left: " + ((this.options.clockSize.width - this.options.centerSize.width)/2).toInt() + "px;\" />");

	this.holder.append(c_img);
	
	
	this.ampm = jQuery("<a id=\"ampm\" />");
	this.ampm.css(this.options.ampmStyles);
	this.updateAmPm();
	this.ampm.css({position:'absolute',
							zIndex:25000,
							display:'block',
							marginTop:((this.options.clockSize.height + (this.options.clockSize.height/4))/2).toInt(),
							marginLeft:((this.options.clockSize.width-20)/2).toInt(),
							cursor:"pointer"});
							
	this.holder.append(this.ampm);
	
	this.moveHands();
	
	this.holder.bind("mousedown", this, function(event){
			if (jQuery(event.target).attr("id") == "ampm")
			{
				event.data.time.hour = ((event.data.time.hour + 12) %24);
				event.data.updateAmPm();
				event.data.onChange(event.data);
			}
			else
			{
				var coord = event.data.holder.position();
				coord.height = event.data.holder.outerHeight();
				coord.width = event.data.holder.outerWidth();

				var ang = event.data.clickAngle({x:event.clientX, y:event.clientY}, coord);
				var h_ang = (event.data.time.hour%12) * 30;
				var m_ang = event.data.time.minute * 6;
							
				event.data.moveEl['move'] = true;
				event.data.moveEl['coord'] = coord;
				
				if (Math.abs(ang - m_ang) < Math.abs(ang - h_ang))
					event.data.moveEl['el'] = "minute";
				else if(Math.abs(ang - m_ang) > Math.abs(ang - h_ang))
					event.data.moveEl['el'] = "hour";
				else {
					if (jQuery(event.target).css("backgroundImage").indexOf(event.data.options.hourHandImage) != -1)
						event.data.moveEl['el'] = "hour";
					else
						event.data.moveEl['el'] = "minute";
				}
			}
		});
	
	this.holder.bind("mouseup", this, function(event){
			event.data.moveEl = {};
			event.data.moveEl['move'] = false;
		});
	
	this.holder.bind("mousemove", this, function(event){
			if (event.data.moveEl['move'])
			{
				var add;
				
				var ang = event.data.clickAngle({x:event.clientX, y:event.clientY}, event.data.moveEl.coord);
				if (event.data.moveEl.el == "hour") var ang_by = 30;
				else var ang_by = 6;
			
				if (event.data.moveEl.el == "hour"){
					var h = (ang/ang_by).toInt();
					if (!isNaN(h))
						event.data.time.hour = h;
					
					if (event.data.ampm.innerHTML == event.data.options.lang.pm)
						event.data.time.hour = (event.data.time.hour+12)%24;
				}
				else{
					var m = (ang/ang_by).toInt();
					if (!isNaN(m))
						event.data.time.minute = m;
				}
											
				event.data.moveHands();
				
				event.data.onChange(event.data);
			}
		});
};