<!-- ===========================================================================
	
	msgbuttonevents.htc

	Last update: 6/29/2005 11:42 AM

	Depends on:

   ======================================================================== -->

<public:component lightweight="true">

<public:attach event="oncontentready" onevent="initialize();" />
<public:attach event="onmouseover" onevent="return handleMouseEvent();" />
<public:attach event="onmouseout" onevent="return handleMouseEvent();" />
<public:attach event="onmousedown" onevent="return handleMouseEvent();" />
<public:attach event="onmouseup" onevent="return handleMouseEvent();" />
<public:attach event="ondragstart" onevent="return handleDragStart();" />
<public:attach event="onpropertychange" onevent="return handlePropertyChange();"/>


<script language="JavaScript1.2">


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//	Constants
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------

var kEventClass_Over = "Over";
var kEventClass_Down = "Down";
var kEventClass_Disabled = "Disabled";
var kEventClass_Separator = "-";

var kEventBehaviors = {
	mouseover:		{ add: kEventClass_Over, handler: onMouseOver },
	mouseout:		{ remove: [kEventClass_Over, kEventClass_Down] },
	mousedown:		{ add: kEventClass_Down, handler: onMouseDown },
	mouseup:		{ remove: kEventClass_Down, handler: onMouseUp },
	enabled:		{ remove: kEventClass_Disabled },
	disabled:		{ add: kEventClass_Disabled, remove: [kEventClass_Over, kEventClass_Down] }
};


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//	Globals
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------

gIsMouseDown = false;
gEnabled = true;


// ===========================================================================
// 	initialize
// ===========================================================================
function initialize()
{
		// remember the element's default class as the base class, which we'll
		// use later to build the over, down and disabled classes.  we need to 
		// grab the className before we set gEnabled, because that will set our
		// class to Disabled if it's false.
	element.baseClassName = element.className;

		// if we don't have an enabled attribute, create a default one and set 
		// it to true.  for some reason, setting disabled sometimes doesn't 
		// trigger onpropertychange (it seems to not work if width and height 
		// styles are set), so we have to use "enabled" instead.
	var enabled = element.getAttribute("enabled");

	if (enabled == null) {
		element.setAttribute("enabled", true);
	}

	setEnabled(getAttributeAsBoolean("enabled"));
}


// ===========================================================================
// 	handleMouseEvent
// ===========================================================================
function handleMouseEvent(
	inEvent)
{
	inEvent = inEvent || window.event;

	if (!gEnabled && inEvent.type != "disabled") {
			// ignore events if we're disabled, but let the "enabled" pseudo-event
			// go through so it will set the className correctly
		return;
	}

		// ignore mouseover and mouseout events when they're triggered by moving
		// over elements that are contained by this element
	switch (inEvent.type) {
		case "mouseover":
			if (element.contains(inEvent.fromElement)) {
				return;
			}
			break;

		case "mouseout":
			if (element.contains(inEvent.toElement)) {
				return;
			}
			break;
	}

	var classInfo = kEventBehaviors[inEvent.type];

	if (classInfo) {
		if (classInfo.remove) {
			removeClass(classInfo.remove);
		}

		if (classInfo.add) {
			addClass(classInfo.add);
		}

		if (classInfo.handler) {
			classInfo.handler(inEvent);
		}
	}
}


// ===========================================================================
// 	onMouseOver
// ===========================================================================
function onMouseOver(
	inEvent)
{
	if (gIsMouseDown) {
		addClass(kEventClass_Down);
	}
}


// ===========================================================================
// 	onMouseDown
// ===========================================================================
function onMouseDown(
	inEvent)
{
	gIsMouseDown = true;
	
		// attach a handler for mouseup so that if the user drags out of the 
		// button while the mouse is down, we'll know to reset gIsMouseDown
	element.document.body.attachEvent("onmouseup", handleMouseEvent);
}


// ===========================================================================
// 	onMouseUp
// ===========================================================================
function onMouseUp(
	inEvent)
{
	gIsMouseDown = false;

		// the mouse button is up, so we no longer need this handler
	element.document.body.detachEvent("onmouseup", handleMouseEvent);
}


// ===========================================================================
// 	handleDragStart
// ===========================================================================
function handleDragStart(
	inEvent)
{
	inEvent = inEvent || window.event;

		// cancel the drag so that if the user can't drag an image out of a button
	inEvent.returnValue = false; 
	inEvent.cancelBubble = true; 
	
	return false;
}


// ===========================================================================
// 	handlePropertyChange
// ===========================================================================
function handlePropertyChange(
	inEvent)
{
	inEvent = inEvent || window.event;

	if (inEvent.propertyName == "enabled") {
			// we need to update the current class as soon as the disabled 
			// attribute is changed
		setEnabled(getAttributeAsBoolean("enabled"));
	}
}


// ===========================================================================
// 	setEnabled
// ===========================================================================
function setEnabled(
	inValue)
{
	gEnabled = inValue;

	if (gEnabled) {
			// trigger an "enabled" pseudo-event, which will cause the appropriate
			// classname to be applied
		handleMouseEvent({ type: "enabled" });
	} else {
			// trigger a "disabled" pseudo-event, which will cause the appropriate
			// classname to be applied
		handleMouseEvent({ type: "disabled" });
	}
}


// ===========================================================================
//	getAttributeAsBoolean
// ===========================================================================
function getAttributeAsBoolean(
	inAttributeName) 
{
	var attribute = element.getAttribute(inAttributeName);
	
	if (typeof attribute != "boolean") {
		if (attribute == null) {
			attribute = false;
		} else if (typeof attribute == "string") {
			attribute = attribute.toLowerCase();
			attribute = (attribute == "true" || attribute == "1" || attribute == "yes");
		} else {
			attribute = new Boolean(attribute);
		}
	}

	return attribute;
}


// ===========================================================================
//	addClass
// ===========================================================================
function addClass(
	inClass)
{
		// create the class name by adding it to the end of the base class name 
		// so that buttons with different class attributes can have different
		// Over, Down and Disabled states
	var classToAdd = element.baseClassName + kEventClass_Separator + inClass;

	if (element.className.indexOf(classToAdd) > -1) {
			// the new class has already been applied to the element, so return
			// so we don't add it twice
		return;
	}

	element.className += " " + classToAdd;
}


// ===========================================================================
//	removeClass
// ===========================================================================
function removeClass(
	inClass)
{
	if (!(inClass instanceof Array)) {
		inClass = [inClass];
	}

		// multiple classes may be passed in to be removed at once, so remove 
		// them one at a time
	for (var i = 0; i < inClass.length; i++) {
		var classToRemove = element.baseClassName + kEventClass_Separator + inClass[i];

			// remove the class using a global regex replace just in case the class 
			// was appended extra times.  only remove the space before the class.  
			// if we're removing the first class, then a space will be left at the
			// beginning of the className, which is okay.
		element.className = element.className.replace(
				new RegExp("( " + classToRemove + ")|(" + classToRemove + " )", "g"), "");
	}
}

</script>

</public:component>
