function previewColor(color)
{
	var preview = document.getElementById('colorPreview');
	var pattern = /^[0-9A-F]{6}$/;

	if (color.value.search(pattern) > -1)
	{
		preview.style.backgroundColor = '#' + color.value;
	}

	return true;
}

function Schedule()
{}

Schedule.prototype.moveDivToCursor = function(event, d)
{
	var x = 0;
	var y = 0
	var xCorrection = 0;
	var yCorrection = 0;

	if (document.all)
	{
		x = event.clientX;
		y = event.clientY;
	}
	else
	{
		x = event.pageX;
		y = event.pageY;
	}

	if (self.pageYOffset)
	{
		xCorrection = self.pageXOffset;
		yCorrection = self.pageYOffset;
	}
	else if (document.documentElement && document.documentElement.scrollTop)
	{
		xCorrection = document.documentElement.scrollLeft;
		yCorrection = document.documentElement.scrollTop;
	}
	else if (document.body)
	{
		xCorrection = document.body.scrollLeft;
		yCorrection = document.body.scrollTop;
	}

	if(document.all)
	{
		x += xCorrection;
		y += yCorrection;
	}

	d.style.left = (x + 20) + "px";
	d.style.top = y + "px";
}

Schedule.prototype.toggleInfo = function(event, id, visible)
{
	var divToToggle = document.getElementById(id + '_info');

	if (visible)
	{		
		this.moveDivToCursor(event, divToToggle);
		divToToggle.className = "info shown";
	}
	else
	{
		divToToggle.className = "info hidden";
	}

	return false;
}

function Scheduler()
{
	this.startHour = null;
	this.endHour = null;
	this.temporaryEndHour = null;
	this.hourClassName = "hour";
	this.minimumInterval = 60;
}

Scheduler.prototype.startHour;
Scheduler.prototype.endHour;
Scheduler.prototype.temporaryEndHour;
Scheduler.prototype.minimumInterval;
Scheduler.prototype.hourClassName;

Scheduler.prototype.initHours = function()
{
	var input = document.getElementById('availability');
	var alreadySent = input.value != '';
	var count = 0;

	var divs = document.getElementsByTagName("div");
	for (var i = 0; i < divs.length; i++)
	{
		var div = divs[i];

		// Cancels the selction for IE.
		if ((div.className == "day" || div.className == "hours" || div.className == "hour") && (typeof div.onselectstart !== 'undefined'))
			div.onselectstart = function() { return false; };

		// Sets the basic propreties of the hours.
		if (div.className == this.hourClassName)
		{
			div.isStart = false;
			div.isTmpEnd = false;
			div.isChosen = false;

			if (alreadySent)
			{
				var index = input.value.indexOf(div.id.substr(5) + ',');
				if (index > -1)
				{
					div.isChosen = true;
					var end = input.value.substr(index + 13, 12);
					var startTime = this.decodeIdToHour(div.id);
					var endTime = this.decodeIdToHour('hour_' + end);
					count = (endTime - startTime) / 3600000;
				}

				if (count-- > 0)
				{
					div.isChosen = true;
				}

				this.setClassName(div);
			}
		}
	}
}

Scheduler.prototype.setClassName = function(div)
{
	var name = this.hourClassName;

	if (div.isChosen && div.isStart && div.isTmpEnd)
		name += " all-mode";
	else if (div.isChosen && div.isStart)
		name += " chosen-start-mode";
	else if (div.isChosen && div.isTmpEnd)
		name += " chosen-end-mode";
	else if (div.isStart && div.isTmpEnd)
		name += " start-end-mode";
	else if (div.isChosen)
		name += " chosen";
	else if (div.isStart)
		name += " start";
	else if (div.isTmpEnd)
		name += " end"

	div.className = name;
}

Scheduler.prototype.setStartHour = function(hourId)
{
	// Resets the selector for the start.
	if (this.startHour != null)
	{
		this.startHour.isStart = false;
		this.startHour.isTmpEnd = false;
		this.setClassName(this.startHour);
		this.startHour = null;
	}

	// Reset the selection for the temporary end.
	if (this.temporaryEndHour != null)
	{
		this.temporaryEndHour.isStart = false;
		this.temporaryEndHour.isTmpEnd = false;
		this.setClassName(this.temporaryEndHour);
		this.temporaryEndHour = null;
	}

	// Do we have a valid hourId?
	if (hourId != '')
	{
		this.startHour = document.getElementById(hourId);
		this.startHour.isStart = true;
		this.startHour.isTmpEnd = true;
		this.setClassName(this.startHour);
	}
	
	return false;
}

Scheduler.prototype.setEndHour = function(hourId)
{
	if (this.startHour != null)
	{
		// Clean the selection.
		this.startHour.isStart = false;
		this.startHour.isTmpEnd = false;
		if (this.temporaryEndHour != null)
		{
			this.temporaryEndHour.isStart = false;
			this.temporaryEndHour.isTmpEnd = false;
		}

		// Sets the real end and select all the hours.
		this.endHour = document.getElementById(hourId);
		this.toggleMiddleHours();

		// Reset the values for a new selection.
		this.startHour = null;
		this.endHour = null;
		this.temporaryEndHour = null;
	}
	return false;
}

Scheduler.prototype.setTemporaryEndHour = function(hourId)
{
	if (this.startHour != null)
	{
		// Cleans the previous limit of the selection.
		if (this.temporaryEndHour != null)
		{
			this.temporaryEndHour.isStart = false;
			this.temporaryEndHour.isTmpEnd = false;
			this.setClassName(this.temporaryEndHour);
		}
		
		var start = this.decodeIdToHour(this.startHour.id);
		var end = this.decodeIdToHour(hourId);

		// Sets the new limit of the selection.
		this.temporaryEndHour = document.getElementById(hourId);

		// Are we going backward? If so, we flip the conditions. (Tmp = Start, Start = Tmp)
		if (start.valueOf() > end.valueOf())
		{
			this.temporaryEndHour.isStart = true;
			this.temporaryEndHour.isTmpEnd = false;
			this.startHour.isTmpEnd = true;
			this.startHour.isStart = false;
		}
		// Are the start and temporary the same? If so, let's handle it.
		else if (start.valueOf() == end.valueOf())
		{
			this.startHour.isTmpEnd = true;
			this.startHour.isStart = true;
		}
		// We are going forward and both divs are not the same.
		else
		{
			this.temporaryEndHour.isStart = false;
			this.temporaryEndHour.isTmpEnd = true;
			this.startHour.isTmpEnd = false;
			this.startHour.isStart = true;
		}

		// Set the layout of both divs involved in the selection.
		this.setClassName(this.startHour);
		this.setClassName(this.temporaryEndHour);
	}
	
	return false;
}

Scheduler.prototype.toggleMiddleHours = function()
{
	var start = this.decodeIdToHour(this.startHour.id);
	var end = this.decodeIdToHour(this.endHour.id);

	// Is the endHour before the start hour? If so, we must go backward in time.
	var increment = this.minimumInterval;
	if (start.valueOf() > end.valueOf())
		increment = -1 * increment;

	while (start.valueOf() != end.valueOf())
	{
		this.toggleHour(this.encodeHourToId(start));
		start.setUTCMinutes(start.getUTCMinutes() + increment);
	}

	this.toggleHour(this.endHour.id);
}

Scheduler.prototype.toggleHour = function(hourId)
{
	var div = document.getElementById(hourId);
	div.isChosen = !div.isChosen;
	this.setClassName(div);
}

Scheduler.prototype.decodeIdToHour = function(hourId)
{
	// Typical hourId : hour_200904270830
	var year = hourId.substring(5, 9);
	var month = hourId.substring(9, 11) - 1; // Months are from 0 to 11 not 1 to 12.
	var day = hourId.substring(11, 13);
	var hour = hourId.substring(13, 15);
	var min = hourId.substring(15);

	var date = new Date();
	date.setUTCFullYear(year, month, day);
	date.setUTCHours(hour, min, 0, 0);

	return date;
}

Scheduler.prototype.encodeHourToId = function(datetime)
{
	var split = new Array(datetime.getUTCFullYear(),
						  datetime.getUTCMonth() + 1, // Months are from 0 to 11 not 1 to 12.
						  datetime.getUTCDate(),
						  datetime.getUTCHours(),
						  datetime.getUTCMinutes());

	for (var i = 0; i < split.length; i++)
		if (split[i] < 10)
			split[i] = "0" + split[i];

	return "hour_" + split.join("");
}

Scheduler.prototype.generateAvailableHours = function()
{
	var value = '';
	var start = '';
	var lastHour = null;

	var input = document.getElementById('availability');
	var hourDivs = document.getElementsByTagName('div');

	for (var i = 0; i < hourDivs.length; i++)
	{
		var hourDiv = hourDivs[i];
		if (hourDiv.className.indexOf('hour') > -1)
		{	
			if (hourDiv.className != "hours")
			{
				if (hourDiv.isChosen)
				{
					if (start == '')
					{
						start = hourDiv.id.substr(5);
					}
				}
				else
				{
					if (start != '')
					{
						value += start + ',' + hourDiv.id.substr(5) + ';';
						start = '';
					}
				}
			}
			else if (hourDiv.className == "hours" && start != '')
			{
				// Once we reached the end of the day, we have to add an entry.
				var startDate = this.decodeIdToHour('hour_' + start);
				startDate.setUTCDate(startDate.getUTCDate() + 1);
				startDate.setUTCHours(0);
				value += start + ',' + this.encodeHourToId(startDate).substr(5) + ';';
				start = '';
			}

			// Keep the last hour of the two weeks.
			lastHour = hourDiv;
		}
	}

	// The last hour of the second week was selected. We have to set the end value manually.
	if (start != '')
	{
		var date = this.decodeIdToHour(lastHour.id);
		date.setUTCHours(date.getUTCHours() + 1);
		value += start + ',' + this.encodeHourToId(date).substr(5) + ';';
	}

	input.value = value;
}

var schedule1 = new Schedule();
var schedule2 = new Schedule();
var scheduler = new Scheduler();
