addService("FileTransfer", function(){
	
	// Associative array of source windows to uuids (key is the uuid)
	var sources = new Array();
  var fileTransfers = {}; // Mapping of id to XMLHttpRequest

	// Public
	// Handle requests
	this.exec = function(action, args, callbackId, source, uuid){
		try {
			sources[uuid]=source;
      if (action === 'upload') {
        this.upload(callbackId, uuid, args);
      } else if (action === 'download') {
        this.download(callbackId, uuid, args);
      } else if (action === 'abort') {
        this.abort(callbackId, uuid, args);
      }
			return; // Nothing is returned as Plugin Results are sent from Java code invoking the Javascript postResult method.
		} catch (e) {
			_consoleLog("ERROR: " + e);
		}
	};

  this.upload = function(callbackId, uuid, args) {
    var filePath = args[0];
    var server = args[1];
    var fileKey = args[2];
    var fileName = args[3];
    var mimeType = args[4];
    var params = args[5];
    var trustAllHosts = args[6];
    var chunkedMode = args[7];
    var headers = args[8];
    var id = args[9];

    // Get file for upload
    var formData = new FormData();
    var entry = getService('File').getEntry(filePath);
    var blob = entry.blob;
    formData.append(fileKey, blob);

    // Form XMLHTTPRequest
    var xhr = new XMLHttpRequest();
    xhr.open('POST', server, true);
    xhr.addEventListener("loadend", function (event) {
      delete fileTransfers[id];
      getService('FileTransfer').postResult(JSON.stringify({
        id: callbackId, 
        message: {
          bytesSent: blob.size,
          responseCode: xhr.status,
          response: xhr.response,
          headers: headers
        }, 
        status: 1
      }), uuid);
    });
    fileTransfers[id] = { xhr: xhr, source: filePath, target: server };

    // Send the Data.
    xhr.send(formData);
  }

  this.download = function(callbackId, uuid, args) {
    var source = args[0]; // remote file
    var target = args[1]; // local path
    var trustAllHosts = args[2];
    var id = args[3];

    var xhr = new XMLHttpRequest();
    xhr.open('GET', source);
    xhr.responseType = "blob";
    xhr.onload = function(event) { 
      if (xhr.status != 200) {
        return;
      }

      var parentDirPath = target.lastIndexOf('/') > 0 ? 
                          target.substr(0, target.lastIndexOf('/')) : null;
      var fileName = target.lastIndexOf('/') > 0 ? 
                     target.substr(target.lastIndexOf('/') + 1, target.length) :
                     null;
      var parentDir = getService('File').getEntry(parentDirPath);
      if (!parentDir) {
        return; // invalid dir to save file
      }

      // Add file to file system
      if (parentDir.children[fileName])
        delete parentDir.children[fileName];
      var entry = {
        name: fileName, 
        blob: xhr.response
      };
      parentDir.children[fileName] = entry;
      getService('File').refreshTree();

      delete fileTransfers[id];
      getService('FileTransfer').postResult(JSON.stringify({
        id: callbackId, 
        message: {
          isFile: true,
          isDirectory: false,
          name: name || '',
          fullPath: target
        }, 
        status: 1
      }), uuid);
    };

    xhr.send();
  }

  this.abort = function(callbackId, uuid, args) {
    var id = args[0];
    if (id in fileTransfers) {
      fileTransfers[id].xhr.abort();
      this.postResult(JSON.stringify({
        id: callbackId,
        message: {
          code: 4, // ABORT_ERR
          source: fileTransfers[id].source,
          target: fileTransfers[id].target,
          exception: ""
        },
        status: 1
      }), uuid);
      delete fileTransfers[id];
    }
  }
		
	this.postResult = function(resultString, uuid) {
    // Duplication is bad... Similar method is already in File class
		_consoleLog("Message recieved from FileTransfer" + resultString);
		var source = sources[uuid];
		if ((source != null) && (typeof source !== "undefined")) {
			var result = null;
			try {
				result = JSON.parse(resultString);
			} catch (err) {
				_consoleLog(err.message);
				_consoleLog("Error occured while interpreting: " + resultString);
			}
			if (typeof result === 'object') {
				_consoleLog("posting...");
				try {
					source.postMessage(JSON.stringify(result), "*");
				} catch (err) {
					_consoleLog(err.message);
					_consoleLog("Error occured while stringifying: " + resultString);
				}
				_consoleLog("posted...");
			} else {
				source.postMessage(resultString, "*");
			}
		} else {
			_consoleLog("Error in postResult");
		}
	};

	// Initialization
	{
	}
});
