//set up the RD object
if(!window.RD){
	window.RD = {};
}

if(!RD.XHTML){
	RD.XHTML = {};
}

RD.XHTML.FileLoader = function(aArgs){
    if(aArgs){
		this.init(aArgs);
	}
	
	return this;
}

RD.XHTML.FileLoader.MaxChunkSize = 1900;

RD.XHTML.FileLoader.prototype.init = function(aArgs){
    this.fileUrl = aArgs.fileUrl;
	this.loadWhole = (aArgs.loadWhole!=null)?aArgs.loadWhole:false;
	this.callbackObject = aArgs.callbackObject?aArgs.callbackObject:window;
	this.callbackFunction = aArgs.callbackFunction;

	if(!this.loadWhole && aArgs.loadFileScript){
		this.chunkSize = aArgs.chunkSize;
		if(!this.chunkSize || this.chunkSize > RD.XHTML.FileLoader.MaxChunkSize){
			this.chunkSize = RD.XHTML.FileLoader.MaxChunkSize;
		}
		else if( this.chunkSize < 2 ){
			this.chunkSize = 2;
		}

		this.id = (aArgs.id!=null)?aArgs.id:RD.getUniqueId();
		this.excludeUrls = (aArgs.excludeUrls!=null)?aArgs.excludeUrls:new Array();
		this.fileType = (this.fileUrl && this.fileUrl.indexOf(".js") > -1)?"js":"xml";
		this.oldNode = aArgs.oldNode;
		this.loadFileScript = aArgs.loadFileScript;
		this.curPosition = 0;
		this.totalBytes = 0;
		this.buffer = String.empty;
		this.status  = {};
		this.state = String.empty;
		this.percent = null;
		this.loadFile();
	}
	else if(!aArgs.db){
		this.loadWhole = true;
		getURL(this.fileUrl, this, true);
	}
};

RD.XHTML.FileLoader.prototype.update = function(aContent){
	if(this.percent != 100){
		this.buffer += aContent;
		this.curPosition += aContent.length;
	
		if(this.callbackObject){
			if(this.callbackObject.update){
				this.callbackObject.update(this);
			}
		}

		this.percent = Math.round(this.curPosition / this.totalBytes * 100);
		this.percent = ( this.percent <= 100 )?this.percent:100;

		if(this.percent != 100){
			// get next chunk of file
			this.send();
		}
	}
};

RD.XHTML.FileLoader.prototype.loadFile = function() {
    this.state = "getFileSize";
    this.send("-1", "-1");
};

RD.XHTML.FileLoader.prototype.send = function(start, length) {
    start  = ( start  != null ) ? start  : this.curPosition;
    length = ( length != null ) ? length : this.chunkSize;
    
    var params = [
        "fileUrl="+this.fileUrl,
        "start="+start,
        "length="+length
    ];
    
	var vUrl = this.loadFileScript;
	if(vUrl.endsWith(".php")){
		vUrl += "?";
	}
	else{
		vUrl += "&";
	}
	
    // params should have special characters converted to hex encoding
    // would be a good idea to wrap this in a try/catch block to
    // catch security violations
    getURL(vUrl + params.join("&"), this, true);
};

RD.XHTML.FileLoader.prototype.operationComplete = function(status){
    if( status.success ){
		var vContent = status.responseText;
		var vStatus = null;
		if(this.loadWhole){
			myRE = new RegExp("Not Found", "gi");
			if(vContent.match(myRE)){
				vStatus = {
					success:false
					,responseText:"error: file could not be found: " + this.fileUrl
				};
			}

			this.totalBytes = vContent.length;
			this.buffer = vContent;
			this.percent = 100;
		}	
		else{
			switch(this.state){
				case "getFileSize":
					this.setFileSize(vContent);
					break;
				case "getChunk":  
					this.update(vContent);
					break;
				default:
					alert("Unrecognized state: " + this.state);
					break;
			}
		}
		
		if(this.percent == 100){
			if(this.callbackObject){
				vStatus = {
					success:true
					,responseText:this.buffer
				};

				if(this.callbackObject.update){
					this.callbackObject.update(this);
				}
				else if(this.callbackFunction && typeof(this.callbackFunction) == "string"){
					this.callbackObject[this.callbackFunction](vStatus);
				}
				else if(this.callbackObject.operationComplete){
					this.callbackObject.operationComplete(vStatus);
				}
				else{
					if(typeof this.callbackObject == "string"){
						eval(this.callbackObject + this.callbackFunction)(vStatus);
					}
					else{
						this.callbackObject(vStatus);
					}
				}
			}
		}
    }
	else{
		if(this.loadWhole){
			alert("XMLHttpRequest error\n\n'" + this.fileUrl + "' could not be loaded");
		}
		else{
			//alert(status.content)
			this.status.responseText = "XMLHttpRequest error";
		}
        // should report error here
    }
};

RD.XHTML.FileLoader.prototype.setFileSize = function(aContent){
    if ( aContent.match(/^error/) ){
        // should report error here
		alert(aContent)
    }
	else{
        this.totalBytes = parseInt(aContent, 10);
        // switch to file reading state and initiate file reading
        this.state = "getChunk";
        this.send();
    }
};

