var FileField = function()
{
  var ref = this;
  this.originalName;
	this.dom_label = createElement('div', 'label')
	this.dom_root = createElement('div', 'FileField');
	this.dom_input = createElement('input');
	this.dom_hidden = createElement('input');
	this.dom_hidden.setAttribute ('type', 'hidden');
	this.dom_thumb = createElement('img', 'thumb');
	this.dom_description = createElement('div','description');
	this.sid = new Date().getTime().toString() + Math.round(Math.random() * 100).toString();
	this.dom_iframe = createElement('div','iframe');
	this.downloadURL;
	
	this.dom_status = createElement('div', 'status');
	this.filename = createElement('div','filename');
	this.size = createElement('div','size');
	this.percent = createElement('div','percent');
	this.progressbarback = createElement('div','progressbarback');
	this.timeleft = createElement('div','timeleft');
	
	this.barwidth= 250;
	this.barendswidth = 0;
	
	// If this value is not null, then it will be passed to the upload.cgi script, and then on to upload.php, as the
	// "type" GET parameter.
	this._uploadType = null;

	//log of returned upload.cgi urls (for checking if the upload isnt getting anywhere..)
	this.uploadLog = new Array();

	this.progressbarmiddle = createElement('div','progressbarmiddle');

	// Array of file name extensions which are allowed to be uploaded. Set null to have no restrictions.
	this._allowedExtensions = null;

	this._monitorProgress = true;

	this._getMonitorProgress = function()
	{
		return this._monitorProgress;
	}

	this.setMonitorProgress = function(monitorProgress)
	{
		this._monitorProgress = monitorProgress;
	}
	
	this.dom_root.hook_complete = function()
	{
		// This function is required even though it is empty. Do not remove it.
	}

	this.hook_abort = function()
	{
		// This function is required even though it is empty. Do not remove it.
	}

	this.getAllowedExtensions = function()
	{
		return this._allowedExtensions;
	}

	this.setAllowedExtensions = function(allowedExtensions)
	{
		this._allowedExtensions = allowedExtensions;
	}

	this.hook_start = function()
	{
		// Required empty function. Do not remove.
	}
	
	this.canStartImmediately = function()
	{
		return true;
	}
	
	this.registerPendingUpload = function()
	{
		// Required empty function. Do not remove.
	}
	
	this.showPendingUpload = function()
	{
		// @todo Implement this.
	}
	
	this.draw = function()
	{
		removeAllChildren(this.dom_root);
		this.dom_label.innerHTML = this.label;
		this.dom_input.type = 'file';
		this.dom_input.name = this.name;
    this.dom_input.id = this.id;
		this.dom_root.id = 'file_' + this.sid;
		this.dom_root.dom_download = this.dom_download = createElement('div', 'download');
		this.dom_hidden.name = this.name;
		this.dom_hidden.value = this.value;
		this.dom_description.innerHTML = this.description;

    this.dom_root.appendChild(this.dom_label);
    var action = '/upload/upload.cgi?sid=' + this.sid;
    if(this.getUploadType() !== null)
    {
    	action = action + '&type=' + this.getUploadType();
    }
    this.dom_iframe.innerHTML = '<form enctype="multipart/form-data" method="POST" target="framepost" action="' + action + '" id="uploadForm"></form>';
    this.dom_root.appendChild(this.dom_iframe);
    this.dom_root.appendChild(this.dom_description);
    this.dom_root.appendChild(this.dom_hidden);
    this.dom_root.getElementsByTagName('form')[0].appendChild(this.dom_input);
		
		if(this.value && this.value!='')
		{
       // Should only do this if the file really is an image
      this.dom_thumb.src = this.getDownloadURL();
      this.dom_thumb.onclick = function()
      {
        window.open('/data.php?imageID='+ref.getValue());
      }
		}

    this.dom_root.appendChild(this.dom_thumb);
		this.dom_root.appendChild(this.dom_root.dom_download);
		this.dom_uploading = createElement ('input');
		this.dom_uploading.type = 'hidden';
		this.dom_uploading.value = '0';
		this.dom_uploading.name = 'uploading_' + this.getName();
    this.dom_root.appendChild(this.dom_thumb);
		this.dom_root.appendChild(this.dom_uploading);

		return this.dom_root;
	}  

	var ref = this;

	this.dom_input.onchange = function()
	{
		if(this.value=='')
		{
			return;
		}
		
		if(!ref.canStartImmediately())
		{
			ref.registerPendingUpload();
			ref.showPendingUpload();
			return;
		}
		
		ref.hook_start();
		
    ref.dom_uploading.value = '1';
		var dom_iframe = createElement('div','hidden');
		dom_iframe.innerHTML = '<iframe name="framepost"></iframe>';
		ref.dom_root.appendChild(dom_iframe);
    ref.dom_root.getElementsByTagName('form')[0].submit();
    var request = 'iTotal=-1&iRead=0&iStatus=1&sessionid='+ref.sid+'&dtstart=0';
    
    // If monitoring of upload progress is required, make the first monitoring request.
    // This function will automatically schedule any future requests which might be needed.
    if(ref._getMonitorProgress())
    {
			ref.update('/upload/progress.cgi?'+request);
    }
    else
    {
    	// Normally then hiding the input field is handled by the update function, but in this case then that function is
    	// not called.
    	// This is needed to correct a styling problem.
			ref.getDomRoot().appendChild(createElement('div', 'clear'));
    	ref.dom_input.style.display='none';
    }
	}
	
	this.dom_root.setValue = function(value)
	{
		ref.setValue(value);
	}
	
	this.setOriginalName = function(name)
	{
		this.originalName = name;
	}
	
	this.dom_root.setOriginalFilename = function(originalName)
	{
		ref.originalName = originalName;
	}
	
	this.setValue = function(value)
	{
		this.value=value;
		this.dom_hidden.value = this.value;
	}
	this.getValue = function()
	{
		return this.dom_hidden.value;
	}
	
	//Set the location of the file on the internet, so it can be downloaded.
	this.setDownloadURL = function(url)
	{
		this.downloadURL = url;
	}
	this.getDownloadURL = function()
	{
		return this.downloadURL;
	}
	
	this.getUploadType = function()
	{
		return this._uploadType;
	}
	
	this.setUploadType = function(uploadType)
	{
		this._uploadType = uploadType;
	}
	
	this.uploadInProgress = function ()
	{
		if (this.dom_uploading.value == '0')
		{
			return false;
		}
		else
		{
			return true;
		}
	}
	
	this.disable = function()
	{
		this.dom_input.disabled = true;
	}
	
	this.enable = function()
	{
		this.dom_input.disabled = false;
	}
	
	this.drawStatus = function()
	{
		removeAllChildren(this.dom_status);
		this.dom_status.appendChild(this.filename);
		//this.dom_status.appendChild(this.size);
		//this.dom_status.appendChild(this.percent);
		this.dom_status.appendChild(createElement('div', 'clear'));
		this.dom_status.appendChild(this.progressbarback);
		this.dom_status.appendChild(this.timeleft);
		return this.dom_status;
	}
	
	this.update = function(request)
	{
		try
		{
			this.dom_status.id = 'div_'+this.sid;
			if(ref.dom_uploading.value == 1)
			{
				// file ready to be uploaded or being uploaded

				ref.dom_input.style.display='none';
				var width=0;
				var onresponse = function(data)
				{
					//check upload is actually progressing.
					ref.uploadLog.push(data.url);
					if(!ref.validateUpload())
					{
						alert('There was an error uploading the file, please try again.');
						ref.hook_onremove(ref.sid); //attempt to cancel
						return false;
					}
					
					if(data.status=='Initialising')
					{
						title = ref.dom_input.value;
						var titlearray = new Array();
						
						if(title.indexOf("/")>=0)
						{
							titlearray = title.split("/");
							title = titlearray.pop();
						}
						else if(title.indexOf("\\")>=0)
						{
							titlearray = title.split("\\");
							title = titlearray.pop();
						}
						var fulltitle = title;
						if(title.length>15)
						{
							title = title.substring(0,13)+'..';
						}
						ref.filename.innerHTML = title;
						
						// Make sure the extension provided is an acceptable one.
						var allowedExtensions = ref.getAllowedExtensions();
						if(allowedExtensions !== null)
						{
							var parts = fulltitle.split('\.');
							var extension = parts[parts.length - 1].toLowerCase();
							var found = false;
							for(var x = 0; x < allowedExtensions.length; x++)
							{
								if(allowedExtensions[x] == extension)
								{
									found = true;
									break;
								}
							}
							if(!found)
							{
								// File extension is not allowed.
								notifier.notify('error', 'Please upload files in one of the following formats: ' + allowedExtensions.join(', '));
								ref.hook_abort();
								return;
							}
						}
						
						ref.size.innerHTML = '';
						ref.percent.innerHTML = '0%';
						ref.timeleft.innerHTML = 'Initialising...';
						ref.drawProgress();
					}
					
					if(data.progress)
					{		
						data.progress.total = ref.fsize(data.progress.total);

						if(data.progress.percentage == null)
						{
							width = ref.barwidth-ref.barendswidth;
							ref.progressbarmiddle.style.width=width+"px";
							
							ref.filename.onclick = function()
							{
								ref.hook_redirectPDF();
							}

							ref.percent.innerHTML = '100%';
							ref.timeleft.innerHTML = 'Processing file, please wait...';
							ref.dom_status.className += ' status_complete';
							ref.size.innerHTML = "&nbsp;("+data.progress.total+')';
							return;
						}
						
						//need to round up the %
						width = Math.ceil(ref.barwidth * (data.progress.percentage/100)-ref.barendswidth);
						ref.percent.innerHTML = Math.round(data.progress.percentage)+'%';
						ref.timeleft.innerHTML = 'Approx '+data.progress.timeleft+' remaining';
						try
						{
							ref.progressbarmiddle.style.width=width+"px";
						}
						catch(e)
						{
						}
					}
					
					// Schedule another progress check if monitoring is still enabled.
					if(ref._getMonitorProgress())
					{
						setTimeout(function(){ref.update(data.url)},data.pole);
					}
				}
				var ticket = requestProcess.add(new Request('GET', request, null, onresponse, function(){}));
			}
			else
			{
				ref.dom_download.innerHTML = '';
				return;
			}
		}
		catch(e)
		{
		}
	}
	
	/***********************
	 * Check the polling URLs history to see if file is still uploading OK
	 */
	this.validateUpload = function()
	{
		//get the last few elements in this.uploadLog, if they are the same, then upload probably stalled/halted/broken
		if(this.uploadLog.length > 7)
		{
			var previous;
			for(var x = this.uploadLog.length-6; x < this.uploadLog.length; x++)
			{
				if(previous)
				{
					if(this.uploadLog[x] != previous)
					{
						return true;
					}
				}
				
				previous = this.uploadLog[x];
			}
			
			//all elements must have been the same if we get here..
			return false;
		}
		else
		{
			//not enough data to prove invalid, so just presume valid.
			return true;
		}
	}
	
	this.drawProgress= function()
	{
		removeAllChildren(this.progressbarback);
		
		var progressbar = createElement('div','progressbar');
		var progressbarleft = createElement('div','progressbarleft');
		var progressbarright = createElement('div','progressbarright');
		var progressbarborder = createElement('div','progressbarborder');
		var clear = createElement('div','clear');

		progressbar.appendChild(progressbarleft);
		progressbar.appendChild(this.progressbarmiddle);
		progressbar.appendChild(progressbarright);
		progressbar.appendChild(clear);

		this.progressbarback.appendChild(progressbar);
		this.progressbarback.appendChild(progressbarborder);
	}
	
	this.fsize = function(size)
	{
		var range = new Array('', 'K', 'M', 'G');
		
		for(var i = 0; size >= 1024 && i < range.length; i++)
		{
			size /= 1024;
		}
		return Math.round(size,2)+range[i]+'B';
	}
}
FileField.prototype = new FormField();

