// THIS CODE IS NOT APPROVED FOR USE IN/ON ANY OTHER UI ELEMENT OR PRODUCT COMPONENT. 
// Copyright (c) 2007 Renderspace. All rights reserved.


/************************************************/
// scrollbar object
/************************************************/


var SCROLL_UPLEFT = 0;
var SCROLL_PAGEUPLEFT = 1;
var SCROLL_PAGEDOWNRIGHT = 2;
var SCROLL_DOWNRIGHT = 3;
var SCROLL_THUMB = 4;

var ScrollbarSegmentNameList = new Array("scroll_u", "scroll_p", "scroll_p", "scroll_d");


/************************************************/


function ScrollbarObject(parent, id, name, isVertical, isEnabled, isVisible, minRange, maxRange, pageSize, pageStep, lineStep, position) {
	this.base = RenderableObject;
	this.base(parent, id, name, "scrollbar");
	this.setAsFirst();
	this.opacity = 1;
	this.clickTime = 0;
	this.pressTime = 0;
	this.isSelected = false;
	this.isClicked = false;
	this.isVertical = isVertical;
	this.minRange = minRange;
	this.maxRange = maxRange;
	this.pageSize = pageSize;
	this.pageStep = pageStep;
	this.lineStep = lineStep;
	this.position = position;
	this.isThumbPressed = false;
	this.thumbMouseX = 0;
	this.thumbMouseY = 0;
	this.isAnyButtonSelected = false;
	this.isPositionChanged = false;
	
	// create scrollbar segments
	this.scrollBtn = new Array(5);
	for (var i = 0; i < 4; i++) {
		var segName = ScrollbarSegmentNameList[i];
		if (segName != null) segName = (isVertical ? "v" : "h") + segName;
		this.scrollBtn[i] = new ButtonObject(this, 0, null, true, isVisible, false, 0, 0, 0, 0, 1, segName, null, null);
		this.scrollBtn[i].prevIsPressed = false;
	}
	this.scrollBtn[SCROLL_THUMB] = new ScrollbarThumbObject(this, 0, null, true, isVisible, isVertical, 1);
	this.scrollBtn[SCROLL_THUMB].prevIsPressed = false;
	
	this.show(isVisible, isEnabled, 1);
}

ScrollbarObject.prototype = new RenderableObject;


ScrollbarObject.prototype.onRelease = function() {
}



ScrollbarObject.prototype.getIsPositionChanged = function() {
    var isChanged = this.isPositionChanged;
    this.isPositionChanged = false;
    return isChanged;
}
    

ScrollbarObject.prototype.setScrollPos = function(pos) {
	if (pos < this.minRange) pos = this.minRange;
	if (pos > this.maxRange) pos = this.maxRange;
	if (this.position == pos) return pos; // no change
	this.position = pos;
	this.isPositionChanged = true;
	this.setPosition(null, null, null, null);
	return pos;
}


ScrollbarObject.prototype.setRange = function(minRange, maxRange, pageSize) {
	if ((this.minRange == minRange) && (this.maxRange == maxRange) && (this.pageSize == pageSize)) return;
	if (maxRange < minRange) maxRange = minRange;
	this.minRange = minRange;
	this.maxRange = maxRange;
	this.pageSize = pageSize;
	var oldPos = this.position;
	if (this.position < this.minRange) this.position = this.minRange;
	if (this.position > this.maxRange) this.position = this.maxRange;
	if (oldPos != this.position) this.isPositionChanged = true;
	this.setPosition(null, null, null, null);
}


ScrollbarObject.prototype.bringToFront = function() {
	for (var i = 0; i < 5; i++) {
		if (this.scrollBtn[i]) this.scrollBtn[i].bringToFront();
	}
}

	
ScrollbarObject.prototype.show = function(isVisible, isEnabled, opacity) {
	var isInRange = (this.maxRange > this.minRange);
	isEnabled = isEnabled && isInRange;
	if ((this.isVisible == isVisible) && (this.isEnabled == isEnabled) && ((opacity == null) || (this.opacity == opacity))) return true; // no change
	
	this.isVisible = isVisible;
	this.isEnabled = isEnabled;
	if (opacity != null) this.opacity = opacity;
	this.scrollBtn[SCROLL_UPLEFT].show(isVisible, isEnabled, opacity);
	this.scrollBtn[SCROLL_PAGEUPLEFT].show(isVisible, isEnabled, opacity);
	this.scrollBtn[SCROLL_THUMB].show(isVisible && isInRange, isEnabled, opacity);
	this.scrollBtn[SCROLL_PAGEDOWNRIGHT].show(isVisible && isInRange, isEnabled, opacity);
	this.scrollBtn[SCROLL_DOWNRIGHT].show(isVisible, isEnabled, opacity);
	return true;
}


ScrollbarObject.prototype.setPosition = function(x, y, w, h) {
	if (x != null) this.x = x;
	if (y != null) this.y = y;
	if (w != null) this.w = w;
	if (h != null) this.h = h;
	
	var btnSize = SCROLLBAR_SIZE;
	var maxSize = this.isVertical ? this.h : this.w;
	if (btnSize * 2 > maxSize) btnSize = maxSize / 2;
	var thumbSize = ((maxSize - 2 * btnSize) * this.pageSize) / (this.maxRange - this.minRange + this.pageSize);
	if (thumbSize + 2 * btnSize > maxSize) thumbSize = maxSize - 2 * btnSize;
	var thumbPos = ((maxSize - 2 * btnSize - thumbSize) * (this.position - this.minRange)) / (this.maxRange - this.minRange);
	if (this.maxRange <= this.minRange) {
		thumbSize = 0;
		thumbPos = maxSize - 2 * btnSize;
	}
	
	if (this.isVertical) {
		this.scrollBtn[SCROLL_UPLEFT].setPosition(this.x, this.y, this.w, btnSize);
		this.scrollBtn[SCROLL_PAGEUPLEFT].setPosition(this.x, this.y + btnSize, this.w, thumbPos);
		this.scrollBtn[SCROLL_THUMB].setPosition(this.x, this.y + btnSize + thumbPos, this.w, thumbSize);
		this.scrollBtn[SCROLL_PAGEDOWNRIGHT].setPosition(this.x, this.y + btnSize + thumbPos + thumbSize, this.w, this.h - 2 * btnSize - thumbPos - thumbSize);
		this.scrollBtn[SCROLL_DOWNRIGHT].setPosition(this.x, this.y + this.h - btnSize, this.w, btnSize);
	}
	else {
		this.scrollBtn[SCROLL_UPLEFT].setPosition(this.x, this.y, btnSize, this.h);
		this.scrollBtn[SCROLL_PAGEUPLEFT].setPosition(this.x + btnSize, this.y, thumbPos, this.h);
		this.scrollBtn[SCROLL_THUMB].setPosition(this.x + btnSize + thumbPos, this.y, thumbSize, this.h);
		this.scrollBtn[SCROLL_PAGEDOWNRIGHT].setPosition(this.x + btnSize + thumbPos + thumbSize, this.y, this.w - 2 * btnSize - thumbPos - thumbSize, this.h);
		this.scrollBtn[SCROLL_DOWNRIGHT].setPosition(this.x + this.w - btnSize, this.y, btnSize, this.h);
	}
	
	this.show(this.isVisible, true, this.opacity);
}


ScrollbarObject.prototype.onUpdateFrame = function(frameDeltaTime) {
	this.clickTime += frameDeltaTime;
	if (this.clickTime > SCROLLBAR_MINCLICK_WAITTIME) this.pressTime += frameDeltaTime;
	
	var isUpPressed = this.scrollBtn[SCROLL_UPLEFT].getIsPressed();
	var isDownPressed = this.scrollBtn[SCROLL_DOWNRIGHT].getIsPressed();
	var isPageUpPressed = this.scrollBtn[SCROLL_PAGEUPLEFT].getIsPressed();
	var isPageDownPressed = this.scrollBtn[SCROLL_PAGEDOWNRIGHT].getIsPressed();
	
	var newPos = this.position;
	if      (isUpPressed && !this.scrollBtn[SCROLL_UPLEFT].prevIsPressed) {this.clickTime = 0; newPos -= this.lineStep;}
	else if (isDownPressed && !this.scrollBtn[SCROLL_DOWNRIGHT].prevIsPressed) {this.clickTime = 0; newPos += this.lineStep;}
	else if (isPageUpPressed && !this.scrollBtn[SCROLL_PAGEUPLEFT].prevIsPressed) {this.clickTime = 0; newPos -= this.pageStep;}
	else if (isPageDownPressed && !this.scrollBtn[SCROLL_PAGEDOWNRIGHT].prevIsPressed) {this.clickTime = 0; newPos += this.pageStep;}
		
	if ((this.clickTime > SCROLLBAR_MINCLICK_WAITTIME) && (this.pressTime > SCROLLBAR_MINCLICK_REPEATTIME)) {
		if      (isUpPressed) newPos -= this.lineStep;
		else if (isDownPressed) newPos += this.lineStep;
		else if (isPageUpPressed) newPos -= this.pageStep;
		else if (isPageDownPressed) newPos += this.pageStep;
		this.pressTime = 0;
	}
	
	if (newPos < this.minRange) newPos = this.minRange;
	if (newPos > this.maxRange) newPos = this.maxRange;
	if (newPos != this.position) {
		this.position = newPos;
		this.isPositionChanged = true;
		this.setPosition(this.x, this.y, this.w, this.h);
	}
	
	this.scrollBtn[SCROLL_UPLEFT].prevIsPressed = isUpPressed;
	this.scrollBtn[SCROLL_DOWNRIGHT].prevIsPressed = isDownPressed;
	this.scrollBtn[SCROLL_PAGEUPLEFT].prevIsPressed = isPageUpPressed;
	this.scrollBtn[SCROLL_PAGEDOWNRIGHT].prevIsPressed = isPageDownPressed;
	
	return true;
}


ScrollbarObject.prototype.onMouseMove = function(mouseEventArgs, isHandled) {
	if (!this.isEnabled || !this.isVisible) return false;
	
	// get and save current and delta mouse coordinates
	var mousePos = getMousePosition(mouseEventArgs);
	var mouseX = mousePos.x;
	var mouseY = mousePos.y;
	
	this.isAnyButtonSelected = false;
	for (var i = 0; i < 5; i++) {
		this.isAnyButtonSelected = this.isAnyButtonSelected || this.scrollBtn[i].isSelected;
	}
	
	if (this.isThumbPressed) {
		var delta = this.isVertical ? (mousePos.y - this.thumbMouseY) : (mousePos.x - this.thumbMouseX);
		
		if (delta != 0) {
			var btnSize = SCROLLBAR_SIZE;
			var maxSize = this.isVertical ? this.h : this.w;
			if (btnSize * 2 > maxSize) btnSize = maxSize / 2;
			var thumbSize = ((maxSize - 2 * btnSize) * this.pageSize) / (this.maxRange - this.minRange + this.pageSize);
			if (thumbSize + 2 * btnSize > maxSize) thumbSize = maxSize - 2 * btnSize;
			
			var newPos = this.minRange + delta * (this.maxRange - this.minRange) / (maxSize - 2 * btnSize - thumbSize)
			
			if (newPos < this.minRange) newPos = this.minRange;
			if (newPos > this.maxRange) newPos = this.maxRange;
			if (newPos != this.position) {
				this.position = newPos;
				this.isPositionChanged = true;
				this.setPosition(this.x, this.y, this.w, this.h);
			}
		}
	}
		
	return false; // handled only when processed
}


ScrollbarObject.prototype.onMouseDown = function(mouseEventArgs, isHandled) {
	if (!this.isEnabled || !this.isVisible) return false;
	
	var mousePos = getMousePosition(mouseEventArgs);
	this.clickTime = 0;
	this.isThumbPressed = this.scrollBtn[SCROLL_THUMB].isPressed;
	
	var btnSize = SCROLLBAR_SIZE;
	var maxSize = this.isVertical ? this.h : this.w;
	if (btnSize * 2 > maxSize) btnSize = maxSize / 2;
	var thumbSize = ((maxSize - 2 * btnSize) * this.pageSize) / (this.maxRange - this.minRange + this.pageSize);
	if (thumbSize + 2 * btnSize > maxSize) thumbSize = maxSize - 2 * btnSize;
	var thumbPos = ((maxSize - 2 * btnSize - thumbSize) * (this.position - this.minRange)) / (this.maxRange - this.minRange);
	
	this.thumbMouseX = mousePos.x;
	if (!this.isVertical) this.thumbMouseX -= thumbPos;
	this.thumbMouseY = mousePos.y;
	if (this.isVertical) this.thumbMouseY -= thumbPos;
	return this.isThumbPressed; // handled only when processed
}


ScrollbarObject.prototype.onMouseUp = function(mouseEventArgs, isHandled) {
	if (!this.isEnabled || !this.isVisible) return false;
	this.isThumbPressed = false;
	return false; // handled only when processed
}



/************************************************/
// scrollbar thumb object
/************************************************/


var ScrollbarThumbSegmentNameList = new Array("scroll_ta", "scroll_tb", "scroll_tc", "scroll_td");


/************************************************/


function ScrollbarThumbObject(parent, id, name, isEnabled, isVisible, isVertical, opacity) {
	this.base = RenderableObject;
	this.base(parent, id, name, "scrollbarthumb");
	this.setAsFirst();
	this.isEnabled = false;
	this.opacity = 1;
	this.clickTime = 0;
	this.isPressed = false;
	this.isSelected = false;
	this.isClicked = false;
	this.prevState = -1;
	this.prevOpacity = -1;
	this.isVertical = isVertical;
	
	this.buttonSegments = null;
	
	// create button
	this.buttonSegments = new Array();
	for (var i = 0; i < ScrollbarThumbSegmentNameList.length; i++) {
		var segName = isVertical ? "v" : "h";
		segName += ScrollbarThumbSegmentNameList[i];
		this.buttonSegments.push(createStateImages(rootCanvas, null, null, null, null, null, 1, 
		  segName+"_n.png", segName+"_d.png", segName+"_h.png", segName+"_p.png"));
	}
	
	this.show(isVisible, isEnabled);
}

ScrollbarThumbObject.prototype = new RenderableObject;


ScrollbarThumbObject.prototype.onRelease = function() {
	if (this.buttonSegments != null) {
		for (var i = 0; i < this.buttonSegments.length; i++) {
			this.buttonSegments[i] = deleteStateImages(rootCanvas, this.buttonSegments[i]);
		}
	}
}


ScrollbarThumbObject.prototype.bringToFront = function() {
	if (this.buttonSegments != null) {
		for (var i = 0; i < this.buttonSegments.length; i++) {
			bringStateImagesToFront(null, this.buttonSegments[i]);
		}
	}
}


ScrollbarThumbObject.prototype.getIsClicked = function() {
	var clicked = this.isClicked;
	this.isClicked = false;
	return clicked;
}


ScrollbarThumbObject.prototype.getIsPressed = function() {
	return this.isPressed && this.isSelected;
}


ScrollbarThumbObject.prototype.updateVisualState = function() {
	var state = IMGSTATE_INVISIBLE;
	if (this.isVisible) {
		if (!this.isEnabled) state = IMGSTATE_DISABLED;
		else if (this.isPressed /*&& this.isSelected*/) state = IMGSTATE_PRESSED;
		else if (this.isSelected) state = IMGSTATE_HOVER;
		else state = IMGSTATE_NORMAL;
	}
	
	if ((state == this.prevState) && (this.opacity == this.prevOpacity)) return;
	this.prevState = state;
	this.prevOpacity = this.opacity;
	
	if (this.buttonSegments != null) {
		for (var i = 0; i < this.buttonSegments.length; i++) {
			changeStateImage(this.buttonSegments[i], state, this.opacity);
		}
	}
}


ScrollbarThumbObject.prototype.show = function(isVisible, isEnabled, opacity) {
	if ((this.isVisible == isVisible) && (this.isEnabled == isEnabled) && ((opacity == null) || (this.opacity == opacity))) return true; // no change
	this.isVisible = isVisible;
	this.isEnabled = isEnabled;
	if (opacity != null) this.opacity = opacity;
	this.isPressed = this.isSelected = false;
	this.updateVisualState();   
	return true;
}


ScrollbarThumbObject.prototype.setPosition = function(x, y, w, h) {
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;

	var state = this.isVisible ? (this.isEnabled ? IMGSTATE_NORMAL : IMGSTATE_DISABLED) : IMGSTATE_INVISIBLE;
	
	if (this.buttonSegments != null) {
		var acSize = 2;
		if (this.isVertical) {if (2 * acSize > h) acSize = h / 2;}
		else {if (2 * acSize > w) acSize = w / 2;}
		if (acSize < 0) acSize = 0;
		var bSize = this.isVertical ? (h - 4) : (w - 4);
		if (bSize < 0) bSize = 0;
		var dSize = bSize;
		if (dSize > 12) dSize = 12;
			
		if (this.isVertical) {
			setStateImagePos(this.buttonSegments[0], x, y, w, acSize, null, state);
			setStateImagePos(this.buttonSegments[1], x, y + 2, w, bSize, null, state);
			setStateImagePos(this.buttonSegments[2], x, y + h - 2, w, acSize, null, state);
			setStateImagePos(this.buttonSegments[3], x, y + (h - dSize) / 2, w, dSize, null, state);
		}
		else {
			setStateImagePos(this.buttonSegments[0], x, y, acSize, h, null, state);
			setStateImagePos(this.buttonSegments[1], x + 2, y, bSize, h, null, state);
			setStateImagePos(this.buttonSegments[2], x + w - 2, y, acSize, h, null, state);
			setStateImagePos(this.buttonSegments[3], x + (w - dSize) / 2, y, dSize, h, null, state);
		}
	}
}


ScrollbarThumbObject.prototype.onUpdateFrame = function(frameDeltaTime, isHandled) {
	this.clickTime += frameDeltaTime;
	return true;
}


ScrollbarThumbObject.prototype.onMouseMove = function(mouseEventArgs, isHandled) {
	if (!this.isEnabled || !this.isVisible) return false;
	
	// get and save current and delta mouse coordinates
	var mousePos = getMousePosition(mouseEventArgs);
	var mouseX = mousePos.x;
	var mouseY = mousePos.y;
	
	this.isSelected = (!isHandled && (mouseX >= this.x) && (mouseY >= this.y) && (mouseX < this.x + this.w) && (mouseY < this.y + this.h));
	this.updateVisualState();
	if (this.isSelected) setCursor("pointer");
	return this.isSelected || this.isPressed; // handled only when processed
}


ScrollbarThumbObject.prototype.onMouseDown = function(mouseEventArgs, isHandled) {
	if (!this.isEnabled || !this.isVisible) return false;
	this.clickTime = 0;
	this.isPressed = this.isSelected && !isHandled;
	this.updateVisualState();
	return this.isSelected; // handled only when processed
}


ScrollbarThumbObject.prototype.onMouseUp = function(mouseEventArgs, isHandled) {
	if (!this.isEnabled || !this.isVisible) return false;
	this.isClicked = this.isPressed && this.isSelected && !isHandled;
	this.isPressed = false;
	this.updateVisualState();
	return this.isSelected; // handled only when processed
}

