// scriptName(this);
function scriptName(thisObj) {

	var scriptName = "Script Name";
	var scriptVersion = "1.0";

	// Include all 1 external JSX files
		#include "~/My%20Documents/CompCodeScripts/First.jsx";

	// Generate Object List
		var objectList = 
		[
			{
				"name": "First",
				"functionName": "compCode_20170515_064415();"
			}
		]


	// Build UI;
		var scriptPalette = scriptBuildUI(thisObj);
		if ((scriptPalette != null) && (scriptPalette instanceof Window)) {
			scriptPalette.center();
			scriptPalette.show();
		} else {
			scriptPalette.layout.layout(true);
		}

		function scriptBuildUI(thisObj) {
			var win = (thisObj instanceof Panel) ? thisObj : new Window("palette", scriptName + " v" + scriptVersion, undefined, {resizeable:true});
				win.spacing = 2;


				var grpContainer = win.add("group");
					grpContainer.orientation = "column";
					grpContainer.spacing = 2;
					grpContainer.alignment = ["fill", "fill"];

					var grpSearch = grpContainer.add("group");
						grpSearch.spacing = 2;
						grpSearch.alignment = ["fill", "top"];

							var searchField = grpSearch.add("edittext", undefined, "");
								searchField.alignment = ["fill", "fill"];

							var btnResetSearch = grpSearch.add("button", undefined, "x");
								btnResetSearch.alignment = ["right", "fill"];
								btnResetSearch.size = [22, 22];

					var myTree = grpContainer.add("listbox", undefined, [], {multiSelect:true});
						generateTree(myTree, objectList);
						myTree.alignment = ["fill", "fill"];
						myTree.preferredSize = [150,300];


			// Button Actions
				btnResetSearch.onClick = function() {
					searchField.text = "";
					myTree.removeAll();
					generateTree(myTree, objectList);
				}

				var timer = null;
				searchField.onChanging = function() {
					if (typeof app.setTimeout === "undefined") { filterIt(); }
					else {
						if (timer !== null) app.cancelTimeout(timer);
						timer = app.setTimeout(filterIt, 300);
					}

					function filterIt() {
						var filteredItems = findItems(objectList, searchField.text.toLowerCase());
						myTree.removeAll();
						generateTree(myTree, filteredItems);
					}
				}

				if (parseInt(app.version) === 11) {
					myTree.addEventListener("mousedown", function(e) {
						if (e.detail == 2)
							executeFunction();
					});
				} else {
					myTree.onDoubleClick = function () {
						executeFunction();
					}
				}

				function executeFunction() {
					var curSelection = myTree.selection;
						curSelection.expanded = !curSelection.expanded;
					if (curSelection.myData) {
						try {
							eval(curSelection.myData.functionName);
							writeLn(curSelection.myData.name + ". Done.");
						} catch (err) {
							alert(err.name + "\nLine: " + err.line.toString() + "\nMessage: " + err.message);
						}
					}
				}

			win.onResizing = win.onResize = function () {this.layout.resize();};

			return win;
		}

	// Other functions
		function generateTree(treeObject, myObject) {
			for (var i = 0; i < myObject.length; i ++) {
				myItem = treeObject.add("item", File.decode(myObject[i]["name"]));
				myItem.myData = myObject[i];
			}
		}

		function findItems(myObject, inputString){
			var newObject = [];
			for (var i = 0, il = myObject.length; i < il; i ++) {
				if (myObject[i].items) {
					var itemsList = findItems(myObject[i].items, inputString);
					if (itemsList.length > 0) {
						var newNode = {name : myObject[i].name, items : itemsList, functionName : myObject[i].functionName};
						newObject.push(newNode);
					}
				} else {
					if (myObject[i]["name"].toLowerCase().match(inputString)) {
						newObject.push(myObject[i]);
					}
				}
			}
			return newObject;
		}

		function openURL(URL) {
			try {
				if (URL.match(/^http:\/\//) === null) URL = "http://" + URL;
				if ($.os.indexOf("Windows") != -1) 	system.callSystem("cmd /c \"explorer " + URL);
				else 								system.callSystem("open " + URL);
			} catch(err){
				alert("Error in openURL function\n" + err.toString());
			}
		}

		function switchUIImage(element, newImg) {
			if (parseFloat(app.version) > 11)
				element.icon = ScriptUI.newImage(newImg);
		}

		function getUserDataFolder () {
			try {
				var userDataFolder = Folder.userData;
				var aescriptsFolder = Folder(userDataFolder.toString() + "/renderTom/" + scriptName + " v" + scriptVersion);
				if (!aescriptsFolder.exists) {
					var checkFolder = aescriptsFolder.create();
					if (!checkFolder) {
						alert ("Error creating \"" + checkFolder.fsName + "\nPlease check the permissions for this folder:\n" + userDataFolder + "\n\nA temp folder will be used instead");
						aescriptsFolder = Folder.temp;
					}
				}
				return aescriptsFolder.toString();
			} catch(err) {
				alert("Permissions issue with user data folder\nPlease give AE full read and write permissions to the ~/Library/Application Support/" + "renderTom" + " folder. ");
			}
		}

		function createResourceFile (filename, binaryString, resourceFolder) {
			try {
				var myFile = new File(resourceFolder + "/" + filename);
				if (!File(myFile).exists) {
					if (!(isSecurityPrefSet())) {
						alert ("This script requires access to write files.\n" +
						"Go to the \"General\" panel of the application preferences and make sure\n" +
						"\"Allow Scripts to Write Files and Access Network\" is checked.");
						app.executeCommand(2359);
						if (!isSecurityPrefSet()) return null;
					}
					myFile.encoding = "BINARY";
					myFile.open( "w" );
					myFile.write( binaryString );
					myFile.close();
				}
				return myFile;
			} catch(err){
				alert("Error in createResourceFile function\n" + err.toString());
			}
		}

		function isSecurityPrefSet(){
			try {
				var securitySetting = app.preferences.getPrefAsLong("Main Pref Section", "Pref_SCRIPTING_FILE_NETWORK_SECURITY");
				return (securitySetting == 1);
			} catch(err){
				alert("Error in isSecurityPrefSet function\n" + err.toString());
			}
		}

}