// AGEA Viewer Application -- sliderWidgets.js
// Copyright (c) 2007-2008 Allen Institute for Brain Science. All Rights Reserved.

function WindowLevelWidget(controlWidth, lowerLimit, upperLimit, lowerRange, upperRange,
							 colormapImage, lowerRangeImage, upperRangeImage,
							 lowerHandle, upperHandle, notificationFunc)
{
	this.sourceObj = null;
	this.tracking = false;
	this.lastEventH = -1;
	
	this.controlWidth = controlWidth;
	this.lowerLimit = lowerLimit;
	this.upperLimit = upperLimit;
	this.scale = controlWidth / (upperLimit - lowerLimit);
	this.lowerRange = (lowerRange - lowerLimit) * this.scale;
	this.upperRange = (upperRange - lowerLimit) * this.scale;
	
	this.container = colormapImage.parentNode;
	this.colormapImage = colormapImage;
	this.lowerRangeImage = lowerRangeImage;
	this.upperRangeImage = upperRangeImage;
	this.lowerHandle = lowerHandle;
	this.upperHandle = upperHandle;
	this.notificationFunc = notificationFunc;
	
	this.registerMouseEvents(this.colormapImage);
	this.registerMouseEvents(this.lowerHandle);
	this.registerMouseEvents(this.upperHandle);
	
	this.doLayout();
	
	lowerRangeImage.controller = this;
	colormapImage.controller = this;
}


WindowLevelWidget.prototype.registerMouseEvents = function(obj)
{
	obj.onmousedown = this.onMouseDown;
	obj.controller = this;
}


WindowLevelWidget.prototype.onMouseDown = function(e)
{
   	if (!e)
		e = window.event;

	sourceObj = null;
	if (window.Event)
	{
		if (e.target)
			sourceObj = e.target;
	}
	else
	{
		sourceObj = window.event.srcElement;
	}
	
	controller = sourceObj.controller;
	if (!sourceObj || !controller || controller.tracking)
		return true;
	
	if (e.pageX)
		controller.anchorPos = e.pageX;
	else if (e.clientX)
		controller.anchorPos = e.clientX;
	controller.startRangeLower = controller.lowerRange
	controller.startRangeUpper = controller.upperRange;
		
	document.onmousemove = WindowLevelWidget.prototype.onMouseMove;
	document.onmouseup = WindowLevelWidget.prototype.onMouseUp;
	document.controller = controller;
	
	controller.tracking = true;
	controller.sourceObj = sourceObj;
	
	return false;
}


WindowLevelWidget.prototype.onMouseMove = function(e)
{
	controller = document.controller;
	if (!controller || !controller.tracking)
		return false;
	
	controller.doDrag(e || window.event);
	
	// document.getElementById('MouseCoordinates').innerHTML = e.clientX + "," + e.clientY + "," + sourceObj.id;
	
	return false;
}


WindowLevelWidget.prototype.onMouseUp = function(e)
{
	controller = document.controller;
	
	document.onmousemove = null;
	document.onmouseup = null;
	document.controller = null;
	
	if (!controller)
		return true;
	
	controller.doDrag(e || window.event);
	
	controller.sourceObj = null;
	controller.tracking = false;
	
	return false;
}


WindowLevelWidget.prototype.doDrag = function(evt)
{
	if (evt.pageX)
		dh = evt.pageX;
	else if (evt.clientX)
		dh = evt.clientX;
	
	dh = dh - this.anchorPos;
	if (this.sourceObj == this.lowerHandle)
	{
		newValue = this.startRangeLower + dh;	 
		if (newValue < 0)
			newValue = 0;
		if (newValue >= this.upperRange)
			newValue = this.upperRange - 1;
		
		if (newValue != this.lowerRange)
		{
			this.lowerRange = newValue;
			this.doUpdate();
		}
	}
	else if (this.sourceObj == this.upperHandle)
	{
		newValue = this.startRangeUpper + dh;	 
		if (newValue <= this.lowerRange)
			newValue = this.lowerRange + 1;
		if (newValue >= this.container.clientWidth)
			newValue = this.container.clientWidth;
		
		if (newValue != this.upperRange)
		{
			this.upperRange = newValue;
			this.doUpdate();
		}
	}
	else if (this.sourceObj == this.colormapImage)
	{
		if (this.startRangeUpper + dh >= this.container.clientWidth)
			dh = this.container.clientWidth - this.startRangeUpper;
		else if (this.startRangeLower + dh <= 0)
			dh = -this.startRangeLower;
		
		if (this.startRangeUpper + dh != this.upperRange)
		{
			this.upperRange = this.startRangeUpper + dh;
			this.lowerRange = this.startRangeLower + dh;
			this.doUpdate();
		}
	}
}


WindowLevelWidget.prototype.doLayout = function()
{
	this.colormapImage.width = this.upperRange - this.lowerRange;
	this.colormapImage.style.left = this.lowerRange + "px";
	
	this.lowerRangeImage.width = this.lowerRange;
	this.upperRangeImage.width = this.controlWidth - this.upperRange;
	this.upperRangeImage.style.left = this.upperRange + "px";
	
	this.lowerHandle.style.left = this.lowerRange + "px";
	this.upperHandle.style.left = this.upperRange + "px";
}


WindowLevelWidget.prototype.doUpdate = function()
{
	this.doLayout();
	this.notificationFunc(this.getLowerRange(), this.getUpperRange(), true);
}


WindowLevelWidget.prototype.getLowerRange = function()
{
	return (this.lowerRange / this.scale) + this.lowerLimit;
}


WindowLevelWidget.prototype.getUpperRange = function()
{
	return (this.upperRange / this.scale) + this.lowerLimit;
}


WindowLevelWidget.prototype.setRange = function(lower, upper)
{
	this.lowerRange = (lower - this.lowerLimit) * this.scale;
	this.upperRange = (upper - this.lowerLimit) * this.scale;
	this.doLayout();
}


function ClusterLevelWidget(controlWidth, lowerLimit, upperLimit, initialValue,
							controlHandle, notificationFunc)
{
	this.sourceObj = null;
	this.tracking = false;
	this.lastEventH = -1;
	
	this.controlWidth = controlWidth;
	this.lowerLimit = lowerLimit;
	this.upperLimit = upperLimit;
	this.scale = controlWidth / (upperLimit - lowerLimit);
	this.controlValue = Math.round((initialValue - lowerLimit) * this.scale);
	
	this.container = controlHandle.parentNode;
	this.controlHandle = controlHandle;
	this.notificationFunc = notificationFunc;
	
	this.registerMouseEvents(this.controlHandle);
	
	this.doLayout();
}


ClusterLevelWidget.prototype.registerMouseEvents = function(obj)
{
	obj.onmousedown = this.onMouseDown;
	obj.controller = this;
}


ClusterLevelWidget.prototype.onMouseDown = function(e)
{
   	if (!e)
		e = window.event;

	sourceObj = null;
	if (window.Event)
	{
		if (e.target)
			sourceObj = e.target;
	}
	else
	{
		sourceObj = window.event.srcElement;
	}
	
	controller = sourceObj.controller;
	if (!sourceObj || !controller || controller.tracking)
		return true;
	
	if (e.pageX)
		controller.anchorPos = e.pageX;
	else if (e.clientX)
		controller.anchorPos = e.clientX;
	controller.startValue = controller.controlValue;
		
	document.onmousemove = ClusterLevelWidget.prototype.onMouseMove;
	document.onmouseup = ClusterLevelWidget.prototype.onMouseUp;
	document.controller = controller;
	
	controller.tracking = true;
	controller.sourceObj = sourceObj;
	
	return false;
}


ClusterLevelWidget.prototype.onMouseMove = function(e)
{
	controller = document.controller;
	if (!controller || !controller.tracking)
		return false;
	
	controller.doDrag(e || window.event);
	
	// document.getElementById('MouseCoordinates').innerHTML = e.clientX + "," + e.clientY + "," + sourceObj.id;
	
	return false;
}


ClusterLevelWidget.prototype.onMouseUp = function(e)
{
	controller = document.controller;
	
	document.onmousemove = null;
	document.onmouseup = null;
	document.controller = null;
	
	if (!controller)
		return true;
	
	controller.doDrag(e || window.event);
	
	controller.sourceObj = null;
	controller.tracking = false;
	
	return false;
}


ClusterLevelWidget.prototype.doDrag = function(evt)
{
	if (evt.pageX)
		dh = evt.pageX;
	else if (evt.clientX)
		dh = evt.clientX;
	
	dh = dh - this.anchorPos;
	if (this.sourceObj == this.controlHandle)
	{
		newValue = this.startValue + dh;	 
		if (Math.round(this.controlValue / this.scale) != Math.round(newValue / this.scale))
		{
			newValue = Math.round(Math.round(newValue / this.scale) * this.scale);
			if (newValue < 0)
    			newValue = 0;
    		
    		widthOffset = this.controlHandle.width / 2;
    		if (newValue >= this.controlWidth - widthOffset)
    			newValue = this.controlWidth - widthOffset;
    		
    		this.controlValue = newValue;
			this.doUpdate();
		}
	}
}


ClusterLevelWidget.prototype.doLayout = function()
{	
	this.controlHandle.style.left = this.controlValue + 1 + "px";
}


ClusterLevelWidget.prototype.doUpdate = function()
{
	this.doLayout();
	this.notificationFunc(this.getValue(), true);
}


ClusterLevelWidget.prototype.getValue = function()
{
	return Math.round((this.controlValue / this.scale) + this.lowerLimit);
}


ClusterLevelWidget.prototype.setValue = function(value)
{
	this.controlValue = (value - this.lowerLimit) * this.scale;
	this.doLayout();
}
