// FileScan Connector - see the options described below (directory, recursion & sort order)
var vrs = "v.2.3";
// 2011.3.24 - changed GetParam() function so that p will never be null
// 2011.4.4 - fixed file count display

// The directory where the file scan begins
//
var baseDir = "C:\\Temp";  // Point this where to look, or use system.getTDIProperty() to externalize this to a file
var recurse = "false"; // "true" = recurse sub-folders
var sortBy = "path"; // can be "path", "name", "size" or "date" (date = last modified)
var direction = "ascending"; // "ascending" or "descending"


logmsg("** FileScan " + vrs + " recursing: " + recurse);
logmsg("**   searching " + baseDir);
logmsg("**   sort by " + sortBy + " (" + direction + ")");


var filePath = [];
var fileName = [];
var fileSize = [];
var lastModList = [];
var fileIndex = 0;
var scanTime = new java.util.Date();
var sortMap = new java.util.TreeMap();
var sortedKeys = null;
var sortIndex = 0;


//===  Function definitions ===

// This version writes to standard out as well, so you can
// see it from the terminal window where you started TDI.
//
function logmsg(msg, logLevel) {
	if (!logLevel)
		logLevel = "INFO";

	main.logmsg(logLevel, msg);
//	java.lang.System.out.println(msg);
}

// Gets TDI property from System-Properties, which is available
// by default, but will not get persisted.
//
function getParam(pname, defvalue) {
	if (typeof(defvalue) == "unknown" || defvalue == null)
		defvalue = "";
		
	var p = connector.getParam(pname);
		
	if (p == null)
		p = defvalue;
	return p.trim().toLowerCase();
}


// Right-justifies a string
//
function rj(str,len) {
	if (!len)
		return str;

	str = "                                                                                         " + str;
	return str.substring(str.length-len);
}


// Scan this directory
//
function getScanList(fName, depth) {
	var fObj = new java.io.File(fName);
	var key = "";
	
	if (typeof(depth) == "undefined")
		depth = 0;

// 	java.lang.System.out.println("---> Scanning " + fName);

	if (fObj == null)
		throw "Scan directory/file (" + fName + ") not found"
	else
	if (fObj.isFile()) {
		fileIndex++;
		filePath[fileIndex] = fObj.getCanonicalPath()
		fileName[fileIndex] = fObj.getName();
		fileSize[fileIndex] = fObj.length();
		lastModList[fileIndex] = fObj.lastModified();
		switch (sortBy.substring(0,1)) {
			case 'n' /*name*/: key = fileName[fileIndex];
					break;
			case 'p' /*path*/: key = filePath[fileIndex];
					break;
			case 's' /*size*/ : key = rj(fileSize[fileIndex],20) + filePath[fileIndex];
					break;
			default /*date*/: key = rj(lastModList[fileIndex],40) + filePath[fileIndex];
		}
		sortMap.put(key, fileIndex);
	logmsg("@@ fileIndex: " + fileIndex + "   key: '" + key + "'");	
	} else
	if (fObj.isDirectory() && (recurse || depth == 0)) {
		var contents = fObj.listFiles();

		if (contents != null)
			for (var i = 0; i < contents.length; i++)
				getScanList(contents[i], depth+1);
	}
}

function selectEntries()
{
 	logmsg("** FileScan scanning " + baseDir + "  ...");

	getScanList(baseDir, 0);

	sortedKeys = sortMap.keySet().toArray();
	logmsg("**    " + (fileIndex) + " file(s) found");
	
	sortIndex = 0;
}

function getNextEntry ()
{
	var next = "";

	if (sortIndex >= sortedKeys.length) {
		result.setStatus (0);
		result.setMessage ("End of input");
		return;
	}

	if (direction.startsWith("a")) // ascending
		fileIndex = sortMap.get(sortedKeys[sortIndex++])
	else
		fileIndex = sortMap.get(sortedKeys[sortedKeys.length - (++sortIndex)])

	entry.setAttribute("filePath", filePath[fileIndex]);
	entry.setAttribute("fileName", fileName[fileIndex]);
	entry.setAttribute("fileLastModified", new java.util.Date(lastModList[fileIndex]));
	entry.setAttribute("fileIndex", new java.lang.Integer(sortIndex));
	entry.setAttribute("fileSize", new java.lang.Long(fileSize[fileIndex]));
	entry.setAttribute("scanTime", scanTime);
	entry.setAttribute("fileCount", new java.lang.Integer(sortedKeys.length - 1));

	fileIndex++;
}


// Test script below for use inside a test AL
/*
selectEntries();
entry = system.newEntry;
work.merge(getNextEntry())
*/
