function VVUpload_ProgressDisplay(clientId, progressLocation, uploadId, uploadFrameId)
{
    // TODO: null circular reference in dispose
    this.id = clientId;
    this.progressArea = document.getElementById(clientId);    
    this.uploadFrameId = uploadFrameId;    
    this.progressInterval = null;
    this.progressRequest = null;
    this.submitComplete = false;
    this.cycleCount = 0;
    
    
    if (uploadId == null)
    {
        uploadId = VVUpload_GenerateGuid();
        
        var uploadIdString = "uploadId=" + uploadId;
            
        var form = document.getElementsByTagName("form")[0];
        
        if (form.action.indexOf("?") != -1)
        {
            var querystart = form.action.indexOf("?");        
            var query = form.action.substr(querystart + 1);
            var uploadIdstart = query.indexOf("uploadId=");
            
            if (uploadIdstart == -1)
                form.action += "&" + uploadIdString;
            else
            {
                var uploadIdend = query.indexOf("&", uploadIdstart);
                
                if (uploadIdend == -1)
                    uploadIdend = query.length;
                
                uploadIdString = query.substr(uploadIdstart, uploadIdend - uploadIdstart);
            }
        }
        else
            form.action += "?" + uploadIdString;
    }
    
    this.progressLocation = progressLocation + "?" + "uploadId=" + uploadId;
        
    //this.isComplete = false;
    //this.inProgress = false;
       
    this.ImportProgressElements();
    
    // TODO: hook up dispose
}

VVUpload_ProgressDisplay.prototype.ImportProgressElements = function()
{
    if (this.progressArea == null)
        return;
        
    //var progressElements = VVUpload_GetElementsByClassNameStartsWith(this.progressArea, "su");
    var progressElements = VVUpload_GetElementsByClassNameStartsWith(document.body, "su");
    
    this.currentFileElements = new Array();
    this.currentFileIndexElements = new Array();
    this.fileCountElements = new Array();
    this.fileCountTextElements = new Array();
    this.speedTextElements = new Array();
    this.timeRemainingTextElements = new Array();
    this.timeElapsedTextElements = new Array();
    this.contentLengthTextElements = new Array();
    this.remainingLengthTextElements = new Array();
    this.transferredLengthTextElements = new Array();
    this.progressBarElements = new Array();
    this.submitButtonElements = new Array();
    this.cancelButtonElements = new Array();
    
    for (var i = 0; i < progressElements.length; i++)
    {
        switch (progressElements[i].className.toLowerCase())
        {
            case "sucurrentfilename":
                this.currentFileElements.push(progressElements[i]);
                            
                break;
            case "sucurrentfileindex":
                this.currentFileIndexElements.push(progressElements[i]);
                            
                break;
            case "sufilecount":
                this.fileCountElements.push(progressElements[i]);
                            
                break;
            case "sufilecounttext":
                this.fileCountTextElements.push(progressElements[i]);
                            
                break;
            case "suspeedtext":
                this.speedTextElements.push(progressElements[i]);
                            
                break;
            case "sutimeremainingtext":
                this.timeRemainingTextElements.push(progressElements[i]);
                            
                break;
            case "sutimeelapsedtext":
                this.timeElapsedTextElements.push(progressElements[i]);
                            
                break;
            case "sucontentlengthtext":
                this.contentLengthTextElements.push(progressElements[i]);
                            
                break;
            case "suremaininglengthtext":
                this.remainingLengthTextElements.push(progressElements[i]);
                            
                break;
            case "sutransferredlengthtext":
                this.transferredLengthTextElements.push(progressElements[i]);
                            
                break;
            case "suprogressbar":
                this.progressBarElements.push(progressElements[i]);
                            
                break;
            case "susubmitbutton":
                this.submitButtonElements.push(progressElements[i]);
                            
                break;
            case "sucancelbutton":
                this.cancelButtonElements.push(progressElements[i]);
                            
                break;
        }
    }
}

VVUpload_ProgressDisplay.prototype.OnSubmit = function()
{
    if (this.uploadFrameId != null)
    {
        this.iframe = document.getElementById(this.uploadFrameId);
    
        if (this.iframe.contentWindow != null)
            this.doc = this.iframe.contentWindow.document;
        else
            this.doc = window.frames[clientId].document;        
    }
    else
    {
        this.doc = document;
    }
    
    //this.inProgress = true;
    
    this.fileCount = 0;
    
    var uploadBoxes = this.doc.getElementsByTagName("input");
    var firstFileText;
    
    for (var i = 0; i < uploadBoxes.length; i++)
    {
        var value = uploadBoxes[i].value;

        if (uploadBoxes[i].type.toLowerCase() == "file" && value != null && value.length > 0)
        {
            this.fileCount++;
            
            if (this.fileCount == 1)
            {               
                var startPos = value.lastIndexOf("\\");
                
                if (startPos == -1)
                    startPos = value.lastIndexOf("/");                
                
                firstFileText = value.substr(startPos + 1);
            }
        }
    }
    
    for (var i = 0; i < VVUpload_ProgressDisplayList.length; i++)
    {
        if (VVUpload_ProgressDisplayList[i] == this)
        {
            this.index = i;
            
            break;
        }
    }

    if (this.fileCount > 0)
    {
        this.fileCountText = this.fileCount + (this.fileCount == 1 ? " file" : " files");
               
        VVUpload_UpdateInnerHTML(firstFileText, this.currentFileElements);
        VVUpload_UpdateInnerHTML(1, this.currentFileIndexElements);
        VVUpload_UpdateInnerHTML(this.fileCount, this.fileCountElements);
        VVUpload_UpdateInnerHTML(this.fileCountText, this.fileCountTextElements);	        
        VVUpload_UpdateInnerHTML("[calculating]", this.speedTextElements);
        VVUpload_UpdateInnerHTML("[calculating]", this.timeRemainingTextElements);
        VVUpload_UpdateInnerHTML("[calculating]", this.timeElapsedTextElements);
        VVUpload_UpdateInnerHTML("[calculating]", this.contentLengthTextElements);
        VVUpload_UpdateInnerHTML("[calculating]", this.remainingLengthTextElements);
        VVUpload_UpdateInnerHTML("[calculating]", this.transferredLengthTextElements);

        VVUpload_SetDisplay(false, this.submitButtonElements);
        VVUpload_SetDisplay(true, this.cancelButtonElements);
    }
    
    this.updateProgressMethod = "VVUpload_ProgressDisplayList[" + this.index + "].UpdateProgress()";
       
    this.UpdateProgress();

    if (this.fileCount > 0)
    {        
        if (this.progressArea != null)
            this.progressArea.style.display = "block";            
    }
}

VVUpload_ProgressDisplay.prototype.UpdateProgress = function()
{
    if (this.progressRequest == null)
    {           
        //this.progressRequest = new XMLHttpRequest();
        this.progressRequest = GetXmlHttp();
    }
    /*else if (this.progressRequest.abort != null)
    {
        this.progressRequest.abort();
    }*/
    
	this.progressRequest.open("GET", this.progressLocation);
	//if (this.progressRequest.onreadystatechange == null)
	//{
        var stateChangeMethod = "VVUpload_ProgressDisplayList[" + this.index + "].progressRequest_StateChange()";
	
        this.progressRequest.onreadystatechange = function() {eval(stateChangeMethod)};
    //}
    this.progressRequest.send("");
}

VVUpload_ProgressDisplay.prototype.progressRequest_StateChange = function()
{
    if (this.progressRequest.readyState == 4)
    {
        var isValidRequest = false;
        
        try
        {
            isValidRequest = (this.progressRequest.status == 200 && this.progressRequest.responseXML != null);
        }
        catch (ex)
        {
            isValidRequest = false;
        }
        
        if (isValidRequest)
        {
            var el = this.progressRequest.responseXML.documentElement;
            
	        if (el != null && el.attributes.length > 0)
	        {
	            if (this.progressArea != null)
	            {
                    var percentComplete = el.getAttribute("percentComplete") + "%";

	                VVUpload_UpdateInnerHTML(el.getAttribute("currentFile"), this.currentFileElements);
	                VVUpload_UpdateInnerHTML(el.getAttribute("currentFileIndex"), this.currentFileIndexElements);
	                VVUpload_UpdateInnerHTML(this.fileCount, this.fileCountElements);
	                VVUpload_UpdateInnerHTML(this.fileCountText, this.fileCountTextElements);	        
	                VVUpload_UpdateInnerHTML(el.getAttribute("speedText"), this.speedTextElements);
	                VVUpload_UpdateInnerHTML(el.getAttribute("timeRemainingText"), this.timeRemainingTextElements);
	                VVUpload_UpdateInnerHTML(el.getAttribute("timeElapsedText"), this.timeElapsedTextElements);
	                VVUpload_UpdateInnerHTML(el.getAttribute("contentLengthText"), this.contentLengthTextElements);
	                VVUpload_UpdateInnerHTML(el.getAttribute("remainingLengthText"), this.remainingLengthTextElements);
	                VVUpload_UpdateInnerHTML(el.getAttribute("transferredLengthText"), this.transferredLengthTextElements);
                    
                    for (var i = 0; i < this.progressBarElements.length; i++)
                        this.progressBarElements[i].style.width = percentComplete;
	            }
        	    
	            var state = el.getAttribute("state");
	            
	            this.cycleCount++;
        	    
	            if (state == "Complete" || state == "Terminated")
	            {
	                //only submit the form one time and wait at least one cycle before trying to submit
					if (this.submitComplete == false && this.cycleCount > 1){
					
						Auersoft.VVUpload.IsUploadInProcess = false;
		                
						if (this.uploadFrameId != null)
						{
							for (var i = 0; i < VVUpload_UploadManagerList.length; i++)
							{
								this.submitComplete = true;
								VVUpload_UploadManagerList[i].SubmitParent();
							}
						}
	                }
	            } 
	            
	            var UploadText = document.getElementById('UploadText');
	           	            
	                      
	            if (state == "Saving"){
					if (UploadText !=null){
						UploadText.innerHTML = "Checking in Uploaded Documents";								            
					}				
					
	            }
	        }
        }
        	    
      window.setTimeout(this.updateProgressMethod, 1000);
    
    }    
}