// THIS CODE IS NOT APPROVED FOR USE IN/ON ANY OTHER UI ELEMENT OR PRODUCT COMPONENT. 
// Copyright (c) 2007 Renderspace. All rights reserved.


/************************************************/
// button object
/************************************************/


var BTN_BORDER_LU = 0;
var BTN_BORDER_U = 1;
var BTN_BORDER_RU = 2;
var BTN_BORDER_L = 3;
var BTN_BORDER_R = 4;
var BTN_BORDER_LD = 5;
var BTN_BORDER_D = 6;
var BTN_BORDER_RD = 7;
var BTN_CENTER = 8;

var ButtonSegmentNameList = new Array("btn_lu", "btn_u", "btn_ru", "btn_l", "btn_r", "btn_ld", "btn_d", "btn_rd");


/************************************************/


function ButtonObject(parent, id, name, isEnabled, isVisible, isToggle, x, y, w, h, opacity, imageName, backColor, tooltipText) {
	this.base = RenderableObject;
	this.base(parent, id, name, "button");
	this.setAsFirst();
	this.parentCanvas = parent && (typeof(parent.parentCanvas) != 'undefined') ? parent.parentCanvas : rootCanvas;
	if (this.parentCanvas == null) this.parentCanvas = rootCanvas;
	this.isEnabled = false;
	this.opacity = 1;
	this.clickTime = 0;
	this.isToggleButton = isToggle;
	this.isPressed = false;
	this.isSelected = false;
	this.isDownState = false; // if toggle-button, true if button is in "down" (pressed) state
	this.isClicked = false;
	this.prevState = -1;
	this.prevOpacity = -1;
	this.buttonImg = null;
	this.buttonSegments = null;
	this.buttonText = null;
	this.buttonTextWidth = 0;
	this.buttonTextClip = null;
	this.buttonBkgnd = null;
	this.tooltipText = tooltipText;
	
	// create button
	if (imageName != null) {
		this.buttonImg = createStateImages(this.parentCanvas, null, null, null, null, null, 0, 
		  imageName+"_n.png", imageName+"_d.png", imageName+"_h.png", imageName+"_p.png");
		changeStateImage(this.buttonImg, isEnabled ? IMGSTATE_NORMAL : IMGSTATE_DISABLED, isVisible ? opacity : 0);
	}
	else {
		this.buttonSegments = new Array(BTN_CENTER + 1);
		for (var i = 0; i < ButtonSegmentNameList.length; i++) {
			var segName = ButtonSegmentNameList[i];
			this.buttonSegments[i] = createStateImages(this.parentCanvas, null, null, null, null, null, 1, 
			  segName+"_n.png", null, segName+"_h.png", segName+"_p.png");
		}
		this.buttonSegments[BTN_CENTER] = null;
		
		if (backColor == null) {
			this.buttonSegments[BTN_CENTER] = createStateImages(this.parentCanvas, null, null, null, null, null, 1, 
			  "btn_c_n.png", null, "btn_c_h.png", "btn_c_p.png");
		}
		else this.buttonBkgnd = createVisualElementFromXaml(this.parentCanvas, '<Rectangle Fill="' + backColor + '" />');
		
		if (name != null) {
			var btnName = getString(name);
			this.buttonTextWidth = getTextWidth(btnName, BUTTON_FONT_SIZE);
			this.buttonText = createVisualElementFromXaml(this.parentCanvas, 
				'<TextBlock FontSize="' + BUTTON_FONT_SIZE + '" Foreground="Black">' + escapeXmlText(btnName)
			  + '<TextBlock.Clip><RectangleGeometry /></TextBlock.Clip>'
			  + '</TextBlock>');
			this.buttonTextClip = getVisualElementClip(this.buttonText);
		}
	}
	
	this.show(isVisible, isEnabled, opacity);
	this.setPosition(x, y, w, h);
}

ButtonObject.prototype = new RenderableObject;


ButtonObject.prototype.onRelease = function() {
	this.buttonImg = deleteStateImages(this.parentCanvas, this.buttonImg);
	if (this.buttonSegments != null) {
		for (var i = 0; i < this.buttonSegments.length; i++) {
			this.buttonSegments[i] = deleteStateImages(this.parentCanvas, this.buttonSegments[i]);
		}
	}
	this.buttonBkgnd = removeVisualElement(this.parentCanvas, this.buttonBkgnd);
	this.buttonText = removeVisualElement(this.parentCanvas, this.buttonText);
}


ButtonObject.prototype.bringToFront = function() {
	bringStateImagesToFront(this.parentCanvas, this.buttonImg);
	if (this.buttonSegments != null) {
		for (var i = 0; i < this.buttonSegments.length; i++) {
			bringStateImagesToFront(this.parentCanvas, this.buttonSegments[i]);
		}
	}
	bringVisualElementToFront(this.parentCanvas, this.buttonBkgnd);
	bringVisualElementToFront(this.parentCanvas, this.buttonText);
}


ButtonObject.prototype.getTooltipValue = function(mousePos) {
	if ((mousePos.x >= this.x) && (mousePos.y >= this.y) && (mousePos.x <= this.x + this.w) && (mousePos.y <= this.y + this.h)) {
		return this.tooltipText;
	}
	return null;
}


ButtonObject.prototype.getIsClicked = function() {
	var clicked = this.isClicked;
	this.isClicked = false;
	return clicked;
}


ButtonObject.prototype.getIsPressed = function() {
	return this.isPressed && this.isSelected;
}


ButtonObject.prototype.setIsDown = function(isDown) {
	this.isDownState = isDown;
	this.isPressed = isDown;
	this.updateVisualState();
}


ButtonObject.prototype.updateVisualState = function() {
	var state = IMGSTATE_INVISIBLE;
	if (this.isVisible) {
		if (!this.isEnabled) state = IMGSTATE_DISABLED;
		else if ((this.isPressed && this.isSelected) || this.isDownState) 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;
	
	changeStateImage(this.buttonImg, state, this.opacity);
	
	var textOfs = 0;
	if (state == IMGSTATE_PRESSED) textOfs += 1;
	this.setTextOffset(textOfs, textOfs);
	
	var textOpacity = this.isEnabled ? this.opacity : this.opacity * 0.25;
	setVisualElementPos(this.buttonText, null, null, null, null, (state >= 0) ? textOpacity : 0);
	
	setVisualElementPos(this.buttonBkgnd, null, null, null, null, (state >= 0) ? this.opacity : 0);
	
	if (this.buttonSegments != null) {
		for (var i = 0; i < this.buttonSegments.length; i++) {
			changeStateImage(this.buttonSegments[i], state, this.opacity);
		}
	}
}


ButtonObject.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 = false;
	this.updateVisualState();   
	return true;
}


ButtonObject.prototype.setTextOffset = function(xOfs, yOfs) {
	if (this.buttonText != null) {
		var btnX = (this.w - this.buttonTextWidth) / 2 + xOfs;
		if (btnX < 0) btnX = 0;
		var btnY = (this.h - BUTTON_FONT_SIZE) / 2 + yOfs;
		if (btnY < 0) btnY = 0;
		var btnW = this.w - btnX;
		var btnH = this.h - btnY;
		setVisualElementPos(this.buttonText, this.x + btnX, this.y + btnY - 2, null, null, null);
		setVisualElementClipRect(this.buttonTextClip, 0, 0, btnW, btnH);
	}
}
	

ButtonObject.prototype.setPosition = function(x, y, w, h) {
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;
	var borderX = (this.buttonSegments != null) ? BUTTON_BORDER_SIZE : 0;
	var borderY = (this.buttonSegments != null) ? BUTTON_BORDER_SIZE : 0;
	if (borderX * 2 > w) borderX = w / 2;
	if (borderY * 2 > h) borderY = h / 2;
	if (borderX < 0) borderX = 0;
	if (borderY < 0) borderY = 0;
	
	var state = this.isVisible ? (this.isEnabled ? IMGSTATE_NORMAL : IMGSTATE_DISABLED) : IMGSTATE_INVISIBLE;
	setStateImagePos(this.buttonImg, x, y, w, h, null, state);
	setVisualElementPos(this.buttonBkgnd, x + borderX, y + borderY, w - 2*borderX, h - 2*borderX, null);

	this.setTextOffset(0, 0);
	
	if (this.buttonSegments != null) {
		setStateImagePos(this.buttonSegments[BTN_BORDER_LU], x, y, borderX, borderY, null, state);
		setStateImagePos(this.buttonSegments[BTN_BORDER_U], x + borderX, y, w - 2*borderX, borderY, null, state);
		setStateImagePos(this.buttonSegments[BTN_BORDER_RU], x + w - borderX, y, borderX, borderY, null, state);
		setStateImagePos(this.buttonSegments[BTN_BORDER_L], x, y + borderY, borderX, h - 2*borderY, null, state);
		setStateImagePos(this.buttonSegments[BTN_BORDER_R], x + w - borderX, y + borderY, borderX, h - 2*borderY, null, state);
		setStateImagePos(this.buttonSegments[BTN_BORDER_LD], x, y + h - borderY, borderX, borderY, null, state);
		setStateImagePos(this.buttonSegments[BTN_BORDER_D], x + borderX, y + h - borderY, w - 2*borderX, borderY, null, state);
		setStateImagePos(this.buttonSegments[BTN_BORDER_RD], x + w - borderX, y + h - borderY, borderX, borderY, null, state);
		setStateImagePos(this.buttonSegments[BTN_CENTER], x + borderX, y + borderY, w - 2 * borderX, h - 2 * borderY, null, state);
	}
}


ButtonObject.prototype.onUpdateFrame = function(frameDeltaTime, isHandled) {
	this.clickTime += frameDeltaTime;
	return true;
}


ButtonObject.prototype.onMouseMove = function(mouseEventArgs, isHandled) {
	if (!this.isVisible || !this.isEnabled) return false;
	
	// get and save current and delta mouse coordinates
	var mousePos = getMousePosition(mouseEventArgs);
	var mouseX = mousePos.x - getVisualElementPosX(this.parentCanvas);
	var mouseY = mousePos.y - getVisualElementPosY(this.parentCanvas);
	
	this.isSelected = /*this.isDownState || */(!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.isToggleButton && this.isPressed); // handled only when processed
}


ButtonObject.prototype.onMouseDown = function(mouseEventArgs, isHandled) {
	if (!this.isVisible || !this.isEnabled) return false;
	
	this.clickTime = 0;
	if (this.isToggleButton) {
		this.isClicked = this.isSelected && !isHandled;
		if (this.isSelected) this.isDownState = (this.isClicked && !this.isDownState);
	}
	
	this.isPressed = (this.isSelected && !isHandled) || this.isDownState;
	this.updateVisualState();
	
	return this.isSelected; // handled only when processed
}


ButtonObject.prototype.onMouseUp = function(mouseEventArgs, isHandled) {
	if (!this.isVisible || !this.isEnabled) return false;

	if (!this.isToggleButton) this.isClicked = this.isPressed && this.isSelected && !isHandled;
	this.isPressed = this.isDownState;
	this.updateVisualState();
	
	if ((this.parentObject != null) && this.parentObject.onButtonClicked && this.isClicked) {
		this.parentObject.onButtonClicked(this);
	}
	return this.isSelected; // handled only when processed
}

