//
// Global this pointer used for timoutcallback.
//
var globalThis = null;

//
// Create the bandwidth detector with the specified image path and image size.
//
function BandwidthDetector(imagePath, imageSize) {
	// Cache this for the working and stop functions
	globalThis = this;
	
	this.imagePath = imagePath;
	this.imageSize = imageSize;
	this.objImage = new Image();
	this.objImage.onload = stopPrivate;
	
	// Create the instance variables and methods
	this.timeout = 500;
	this.downloadEventHandler = null;
	this.objStartTime = null;
	this.objStopTime = null;
	this.objTimerHandle = null;
	
	this.start = start;
	this.setEventHandler = setEventHandler;
	this.getBandwidth = getBandwidth;
}


//
// Set the event handler for the bandwidth detector. It should have three functions defined
// called started(), working(), and completed(). The bandwidth detector will call these 
// methods when the corresponding event occurs.
//
function setEventHandler(downloadEventHandler) {
	this.downloadEventHandler = downloadEventHandler;
}


//
// This method is called to start the bandwidth test and calls the event handler's started() method. 
// Once the event handler's completed() method is called, call getBandwidth() to retrieve the results.
//
function start() {
	// Call the started callback
	if (this.downloadEventHandler != null) {
		var started = this.downloadEventHandler.started;
		if (started != null) {
			started();
		}
	}
	// Start downloading the image
	var currentDate = new Date()
	this.objStartTime = currentDate.getTime();
	this.objStopTime = null;
	this.objImage.src = this.imagePath + "?makeUnique=" + this.objStartTime;
	
	globalThis = this;
	this.objTimerHandle = setTimeout("workingPrivate();", this.timeout);
}


//
// This method returns the bandwidth that was detected by the test. It should only be called after the
// event handler's completed() method is called. If the test is not completed, -1 is returned. The bandwidth
// is returned in kilobits per second.
//
function getBandwidth() {
	// Make sure the test is completed
	if (this.objStopTime == null || this.objStartTime == null) {
		return -1;
	}
	// Calculate the bandwidth
	var iDuration = (this.objStopTime - this.objStartTime) / 1000;  // the number of seconds it took
	var iThroughPut = ((this.imageSize / iDuration) / 1024) * .93;  // .93 to compensate for packet headers
	var iThroughPutBits = (((this.imageSize * 8) / iDuration) / 1024) * .93; // .93 to compensate for packet headers
	iThroughPut = Math.round(iThroughPut * 100);
	iThroughPutBits = Math.round(iThroughPutBits);
	
	return iThroughPutBits;  
}


//
// This fuction calls the registerd event handler's working() method every 500 ms.
//
function workingPrivate() {
	// Call the working callback
	if (globalThis.downloadEventHandler != null) {
		var working = globalThis.downloadEventHandler.working;
		if (working != null) {
			working();
		}
	}
	// Set the timer again
	globalThis.objTimerHandle = setTimeout("workingPrivate();", globalThis.timeout);
}


// 
// This function is called by the image onload event. It records the stopPrivate time and calls
// the event handler's completed() method.
//
function stopPrivate()
{
	// Get the stopPrivate time
	var currentDate = new Date()
	globalThis.objStopTime = currentDate.getTime();
	if (globalThis.objTimerHandle) {
		clearTimeout(globalThis.objTimerHandle);
		globalThis.objTimerHandle = null;
	}
	
	// Call the started callback
	if (globalThis.downloadEventHandler != null) {
		var completed = globalThis.downloadEventHandler.completed;
		if (completed != null) {
			completed();
		}
	}
}

